PHP PDO从多维数组批量插入无法插入MySQL

标签 php mysql sql pdo bulkinsert

我有一个像这样的数组,其中包含很多行,我需要使用 PDO 将其插入 MySQL 数据库

array(3067) {
  [0]=>
  array(2) {
    ["order"]=>
    string(7) "2854811"
    ["consignment"]=>
    string(0) ""
  }
  [1]=>
  array(2) {
    ["blah"]=>
    string(7) "2854811"
    ["whatever"]=>
    string(2) "someval"
  }
  [4]=>
  array(2) {
    ["blah"]=>
    string(7) "2864412"
    ["whatever"]=>
    string(0) ""
  }

我尝试了此处提出的各种建议组合,但每个建议都会收到不同的错误消息

php PDO insert batch multiple rows with placeholders

PDO MySQL: Insert multiple rows in one query

我已经尝试过了

$db->beginTransaction();

$stmt = $db->prepare("INSERT INTO mytable (column1, column2) VALUES (:blah, :whatever)");

foreach($test as $insertRow){

    // now loop through each inner array to match binded values
    foreach($insertRow as $column => $value){
        $stmt->bindParam(":{$column}", $value);
        $stmt->execute();
    }
}

$db->commit();

但我收到此错误消息

Uncaught exception 'PDOException' with message 'SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens

我也尝试过

$sql = 'INSERT INTO mytable (blah, whatever) VALUES ';
$insertQuery = array();
$insertData = array();
$n = 0;
foreach ($input as $row) {
    $insertQuery[] = '(:blah' . $n . ', :whatever' . $n . ')';
    $insertData['blah' . $n] = $row['blah'];
    $insertData['whatever' . $n] = $row['whatever'];
    $n++;
}

if (!empty($insertQuery)) {
    $sql .= implode(', ', $insertQuery);
    $stmt = $db->prepare($sql);
    $stmt->execute($insertData);
}

但我收到此错误消息,该消息没有任何意义,因为“blah”的每个长度都相同

Uncaught exception 'PDOException' with message 'SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'order_number' at row 1625'

如何将我的数组插入到数据库中?如果我必须执行很多次或者只要我能插入一次,我并不挑剔。

编辑

我想做的是读取一个文本文件并将其插入到一个完美运行的数组中,所以我剩下的只是一个大约有 3000 行的关联数组,它们每个都包含一个名为“blah”的字段, “随便”。

获得数组后,我需要将其插入 MySQL 数据库

CREATE TABLE IF NOT EXISTS `tracker` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `blah` varchar(8) NOT NULL,
  `whatever` varchar(25) NOT NULL,
  `input_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB

我最终应该从数组中插入大约 3000 行。

我希望这是有道理的。如果没有我会添加更多

最佳答案

我相信您已经通过这个示例了解了:

$db->beginTransaction();

$stmt = $db->prepare("INSERT INTO mytable (column1, column2) VALUES (:blah, :whatever)");

foreach($test as $insertRow){

   // now loop through each inner array to match binded values
   foreach($insertRow as $column => $value){
      $stmt->bindParam(":{$column}", $value);
      $stmt->execute();
   }
}

$db->commit();

您遇到的问题是您在绑定(bind)适当数量的参数之前调用execute()。相反,您需要先绑定(bind)所有参数,然后调用 execute()

$db->beginTransaction();

$stmt = $db->prepare("INSERT INTO mytable (column1, column2) VALUES (:blah, :whatever)");

foreach($test as $insertRow){

   // now loop through each inner array to match binded values
   foreach($insertRow as $column => $value){
      $stmt->bindParam(":{$column}", $value);
   }

}

// NOW DO EXECUTE
$stmt->execute();

$db->commit();

编辑

针对您的评论,很难准确说出您想要完成的任务,但如果您只收到一条记录,那么这是因为杰拉德提出的内容,这些是单独的查询,需要同时处理。看看这个修订版:

// Start Transaction
$db->beginTransaction();

// Insert each record
foreach($test as $insertRow){

   // Prepare statement
   $stmt = $db->prepare("INSERT INTO mytable (column1, column2) VALUES (:blah, :whatever)");

   // now loop through each inner array to match binded values
   foreach($insertRow as $column => $value){
      $stmt->bindValue(":{$column}", $value);
   }

   // Execute statement to add to transaction
   $stmt->execute();

   // Clear statement for next record (not necessary, but good practice)
   $stmt = null;
}

// Commit all inserts
$db->commit();

关于PHP PDO从多维数组批量插入无法插入MySQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19295239/

相关文章:

php - 用于 backbone.js Web 应用程序的良好、轻量级非 mvc php 框架

php - 从 Laravel 5.3 升级到 Laravel 5.4 空字段转换为 NULL

php - 从一个表中获取所有数据,有时将该表与另一个表相关联

sql - 是否可以向表中插入任意数据?

sql - MySQL 查询动态范围?

sql - Oracle 中的合并表,删除条件引用源表

php - 登录、 session 、用户管理、日志记录模块

PHP json_encode 到 Javascript 未定义/空

php - 通过 CSV 内容 DELETE FROM 查询 MySQL

mysql - 运行此查询而不更改 sql_mode