パラメータ化された一括挿入
-
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);
潜在的な解決策 (から変更) PHP と PDO を使用して単一の MySQL プリペアド ステートメントに配列を挿入する方法) であるように見えます:
$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);
}
パラメータ化されたクエリを使用して一括挿入を実行するより良い方法はありますか?
解決
そうですね、選択肢は 3 つあります。
一度構築すれば複数実行可能。基本的には、1 行に対して 1 回挿入を準備し、それを実行する行をループします。SQLSERVER 拡張機能は、準備後のクエリの再バインドをサポートしていないため (実行する必要があります) 参照を含む汚いハック)それは最良の選択肢ではないかもしれません。
ビルドは 1 回、実行は 1 回です。基本的に、例で述べたように 1 つの巨大な挿入を構築し、それを 1 回バインドして実行します。これは少し汚くて、準備されたクエリがもたらす利点の一部が欠けています。ただし、オプション 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