-
09-10-2019 - |
题
我正在尝试切换一些硬编码查询以使用参数化输入,但是我遇到了一个问题:您如何格式化参数化的批量插入的输入?
目前,代码看起来像这样:
$data_insert = "INSERT INTO my_table (field1, field2, field3) ";
$multiple_inserts = false;
while ($my_condition)
{
if ($multiple_inserts)
{
$data_insert .= " UNION ALL ";
}
$data_insert .= " SELECT myvalue1, myvalue2, myvalue3 ";
}
$recordset = sqlsrv_query($my_connection, $data_insert);
潜在解决方案(从 如何将数组插入单个MySQL准备的语句,w/ php和pdo) 似乎:
$sql = 'INSERT INTO my_table (field1, field2, field3) VALUES ';
$parameters = array();
$data = array();
while ($my_condition)
{
$parameters[] = '(?, ?, ?)';
$data[] = value1;
$data[] = value2;
$data[] = value3;
}
if (!empty($parameters))
{
$sql .= implode(', ', $parameters);
$stmt = sqlsrv_prepare($my_connection, $sql, $data);
sqlsrv_execute($stmt);
}
是否有更好的方法可以完成使用参数化查询的批量插入?
解决方案
好吧,您有三个选择。
构建一次 - 执行多个。基本上,您将插入物准备为一行,然后循环循环执行。由于SQLServer扩展程序不支持查询后的重新固定(您需要做 带有参考的肮脏hacks)这可能不是最好的选择。
构建一次 - 执行一次。基本上,您在示例中所说的,构建一个巨型插入物,将其绑定一次并执行。这有点肮脏,错过了准备的查询带来的一些好处。但是,由于需要从选项1引用参考,我会这样做。我认为构建巨型查询而不是依赖变量引用是更干净的。
构建多个 - 执行倍数。基本上,采用您要做的方法,然后对其进行调整以重新浏览各种记录。这样可以防止过度的查询和“批处理”查询。所以这样的事情:
$sql = 'INSERT INTO my_table (field1, field2, field3) VALUES '; $parameters = array(); $data = array(); $execute = function($params, $data) use ($my_connection, $sql) { $query = $sql . implode(', ', $parameters); $stmt = sqlsrv_prepare($my_connection, $query, $data); sqlsrv_execute($stmt); } while ($my_condition) { $parameters[] = '(?, ?, ?)'; $data[] = value1; $data[] = value2; $data[] = value3; if (count($parameters) % 25 == 0) { //Flush every 25 records $execute($parameters, $data); $parameters = array(); $data = array(); } } if (!empty($parameters)) { $execute($sql, $parameters, $data); }
两种方法都足够了。做您认为最适合您的要求的事情...
其他提示
为什么不只是使用“准备一次,执行多个”方法。我知道您希望它都失败或所有工作,但是交易并不难处理:
http://www.php.net/manual/en/pdo.begintransaction.php
不隶属于 StackOverflow