PDO 准备就绪 在单个查询中插入多行

2022-08-30 06:36:51

我目前正在MySQL上使用这种类型的SQL在一个查询中插入多行值:

INSERT INTO `tbl` (`key1`,`key2`) VALUES ('r1v1','r1v2'),('r2v1','r2v2'),...

在 PDO 上的读数上,使用预准备语句应该比静态查询给我更好的安全性。

因此,我想知道是否可以使用预准备语句生成“使用一个查询插入多行值”。

如果是,我可以知道如何实现它吗?


答案 1

使用 PDO 预准备语句插入多个值

在一个执行语句中插入多个值。为什么,因为根据此页面,它比常规插入更快。

$datafields = array('fielda', 'fieldb', ... );

$data[] = array('fielda' => 'value', 'fieldb' => 'value' ....);
$data[] = array('fielda' => 'value', 'fieldb' => 'value' ....);

更多数据值,或者您可能有一个填充数据的循环。

使用准备好的插入,您需要知道要插入到的字段,以及要创建 ?用于绑定参数的占位符。

insert into table (fielda, fieldb, ... ) values (?,?...), (?,?...)....

这基本上就是我们希望插入语句的样子。

现在,代码:

function placeholders($text, $count=0, $separator=","){
    $result = array();
    if($count > 0){
        for($x=0; $x<$count; $x++){
            $result[] = $text;
        }
    }

    return implode($separator, $result);
}

$pdo->beginTransaction(); // also helps speed up your inserts.
$insert_values = array();
foreach($data as $d){
    $question_marks[] = '('  . placeholders('?', sizeof($d)) . ')';
    $insert_values = array_merge($insert_values, array_values($d));
}

$sql = "INSERT INTO table (" . implode(",", $datafields ) . ") VALUES " .
       implode(',', $question_marks);

$stmt = $pdo->prepare ($sql);
$stmt->execute($insert_values);
$pdo->commit();

尽管在我的测试中,使用多个插入物和具有单个值的常规制备插入物时只有1秒的差异。


答案 2

与巴拉格塔斯先生相同的答案,稍微清晰一些......

最新版本的MySQL和PHP PDO支持多行语句。INSERT

SQL 概述

SQL 将如下所示,假设您想要一个 3 列表。INSERT

INSERT INTO tbl_name
            (colA, colB, colC)
     VALUES (?, ?, ?), (?, ?, ?), (?, ?, ?) [,...]

ON DUPLICATE KEY UPDATE即使使用多行 INSERT 也能按预期工作;附加以下内容:

ON DUPLICATE KEY UPDATE colA = VALUES(colA), colB = VALUES(colB), colC = VALUES(colC)

菲律宾比索概述

您的 PHP 代码将遵循通常的 PDO 调用。$pdo->prepare($qry)$stmt->execute($params)

$params将是要传递给 的所有值的一维数组。INSERT

在上面的例子中,它应该包含9个元素;PDO 将使用每组 3 作为单行值。(插入 3 行,每行 3 列 = 9 个元素数组。

实现

下面的代码是为了清晰而写的,而不是为了效率。如果您愿意,可以使用PHP函数以更好的方式映射或浏览数据。是否可以使用事务显然取决于您的MySQL表类型。array_*()

若:

  • $tblName- 要插入到的表的字符串名称
  • $colNames- 表的列名的一维数组 这些列名必须是有效的MySQL列标识符;如果它们不是,则使用反引号 ('') 将其转义
  • $dataVals- 多维数组,其中每个元素都是 INSERT 值行的一维数组

示例代码

// setup data values for PDO
// memory warning: this is creating a copy all of $dataVals
$dataToInsert = array();

foreach ($dataVals as $row => $data) {
    foreach($data as $val) {
        $dataToInsert[] = $val;
    }
}

// (optional) setup the ON DUPLICATE column names
$updateCols = array();

foreach ($colNames as $curCol) {
    $updateCols[] = $curCol . " = VALUES($curCol)";
}

$onDup = implode(', ', $updateCols);

// setup the placeholders - a fancy way to make the long "(?, ?, ?)..." string
$rowPlaces = '(' . implode(', ', array_fill(0, count($colNames), '?')) . ')';
$allPlaces = implode(', ', array_fill(0, count($dataVals), $rowPlaces));

$sql = "INSERT INTO $tblName (" . implode(', ', $colNames) . 
    ") VALUES " . $allPlaces . " ON DUPLICATE KEY UPDATE $onDup";

// and then the PHP PDO boilerplate
$stmt = $pdo->prepare ($sql);

$stmt->execute($dataToInsert);

$pdo->commit();

推荐