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

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

在PDO的阅读资料中,使用预先准备好的语句应该比静态查询更安全.

因此,我想知道是否可以使用准备好的语句生成"使用一个查询插入多行值".

如果是的话,请问我怎样才能实施呢?

推荐答案

Multiple Values Insert with PDO Prepared Statements

在一个execute语句中插入多个值.为什么,因为根据this page,它比常规插入更快.

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

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

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

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

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

这基本上就是我们希望的INSERT语句的外观.

现在,代码:

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秒的差异.

Php相关问答推荐

当我们使用PHPUnit时,控制台中的--uses param到底起了什么作用以及如何使用?

使用WooCommerce本机产品短码时不考虑价格筛选(_SHORT CODE)

Mysqli_stmt::Execute():结果字段元数据中存在过早的EOF

通过注册在Laravel中分配角色

在PHP中读取JSON

在PHP中,如何将介于0和1之间(包括0和1)的浮点概率转换为数组索引?

WHERE方法不能与有效查询Laravel一起使用

Symfony Validator:如何使用XML表示法验证深度嵌套的数据?

在带有livewire 3的laravel中使用规则方法时,无法进行实时验证

在WooCommercestore 页面上显示库存产品属性的值

用ajax获取文件 - CORS问题&;设置缓存?

MongoDB Laravel Jenssegers 包:插入数据库时​​未定义的类常量PRIMARY

通过ajax发送数据到下拉列表未完全设置为所选

获取 Shopware 6 集合元素的值,PHP

由于 PHP 版本不受支持,如何终止 PHP 脚本?

通过存储库检索 Blade 上的单值数据 出错

PHP 创建 CSV 文件并用波斯语写入

在WooCommerce可变产品中显示所选变体的自定义字段

为什么 AJAX 请求没有通过 is_ajax_request() codeigniter 的条件?

Laravel Websockets 错误:(WebSocket 在建立连接之前关闭)