php PDO使用占位符插入批处理多行

Rob*_*_UK 20 php pdo bulkinsert insert

我希望使用PHP PDO进行多次插入.

我找到的最接近的答案是这一个

如何对嵌件的阵列 - 进入 - 一个单MySQL的准备语句

然而,给出的例子使用?? 而不是真正的占位符.

我已经查看了PHP doc站点上的占位符示例

php.net pdo.prepared-statements

$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':value', $value);
Run Code Online (Sandbox Code Playgroud)

现在让我说我想实现上述但是使用数组

$valuesToInsert = array(
  0 => array('name' => 'Robert', 'value' => 'some value'),
  1 => array('name' -> 'Louise', 'value' => 'another value')
);
Run Code Online (Sandbox Code Playgroud)

如何使用PDO和每次交易多次插入?

我想它会以循环开始?

$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");

foreach($valuesToInsert as $insertRow){

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

然而,上述情况不起作用,但希望能够展示我想要实现的目标

Álv*_*lez 26

首先,?符号真正的占位符(大多数驱动程序允许使用语法,位置和命名占位符).其次,准备好的语句只不过是将原始输入注入SQL语句的工具 - SQL语句本身的语法不受影响.您已经拥有了所需的所有元素:

  • 如何使用单个查询插入多行
  • 如何动态生成SQL
  • 如何使用带有命名占位符的预准备语句.

将它们全部组合在一起是相当微不足道的:

$sql = 'INSERT INTO table (memberID, programID) VALUES ';
$insertQuery = array();
$insertData = array();
$n = 0;
foreach ($data as $row) {
    $insertQuery[] = '(:memberID' . $n . ', :programID' . $n . ')';
    $insertData['memberID' . $n] = $memberid;
    $insertData['programID' . $n] = $row;
    $n++;
}

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


N.B*_*.B. 7

我假设您正在使用InnoDB,因此此答案仅对该引擎(或任何其他具有事务功能的引擎有效,意味着不包括MyISAM).

默认情况下,InnoDB以自动提交模式运行.这意味着每个查询都被视为自己包含的事务.

要将其转换为我们凡人可以理解的内容,这意味着您发出的每个INSERT查询都会强制硬盘通过确认它写下查询信息来提交它.考虑到机械硬盘如何超慢,因为它们每秒的输入输出操作很低(如果我没有记错,平均值是300的IO),这意味着你的5万个查询将会 - 超级慢.

所以你会怎么做?您在一次交易中提交所有50k查询.它可能不是用于各种目的的最佳解决方案,但它会很快.

你这样做:

$dbh->beginTransaction();

$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");

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


$dbh->commit();
Run Code Online (Sandbox Code Playgroud)

  • 'value'变量缺少美元符号:) (2认同)