


[PDO バインディング パラメータ] PHP の PDO 拡張機能を使用してバッチ更新操作を実行します php pdo sqlite php pdo odbc php open pd
Jul 29, 2016 am 08:52 AM最近、データベース テーブルの特定のフィールドをバッチ更新するという要件があり、この要件を実行する際にパラメーターのバインドに PDO が使用されましたが、落とし穴に遭遇しました。
スキームの選択
著者は、バッチ更新について次の解決策を知っています:
1. 1 つずつ更新
これは最も単純な解決策ですが、間違いなく最も効率が低い解決策です。
2. CASE WHEN
以下のような文
<span>UPDATE</span> tbl_test <span>SET</span> val <span>=</span><span>CASE</span> id <span>WHEN</span><span>1</span><span>THEN</span><span>2</span><span>WHEN</span><span>2</span><span>THEN</span><span>3</span><span>END</span><span>WHERE</span> id <span>IN</span>(<span>1</span>, <span>2</span>);
PDOバインディングパラメータ
SQLインジェクションを防ぐために、PDO拡張バインディングパラメータが使用されます。上記の数値は通常変数であるため、パラメーターのバインドが必要です。最初は、ID で構成される文字列を IN 中に変数としてバインドすることを考えていました。最初の実装のコードは次のとおりです。
<span> 1</span> <?<span>php </span><span> 2</span><span>$data</span> = <span>array</span>(<span>array</span>('id' => 1, 'val' => 2), <span>array</span>('id' => 2, 'val' => 3<span>)); </span><span> 3</span><span>$ids</span> = <span>implode</span>(',', <span>array_map</span>(<span>function</span>(<span>$v</span>) {<span>return</span><span>$v</span>['id'];}, <span>$data</span>)); <span>//</span><span>获取ID数组</span><span> 4</span><span>$update_sql</span> = 'UPDATE tbl_test SET val = CASE id'<span>; </span><span> 5</span><span>$params</span> = <span>array</span><span>(); </span><span> 6</span><span>$params</span>[":ids"] = <span>$ids</span><span>; </span><span> 7</span><span>foreach</span>(<span>$data</span><span>as</span><span>$key</span> => <span>$item</span><span>) { </span><span> 8</span><span>$update_sql</span> .= "WHEN :id_" . <span>$key</span> . "THEN :val_" . <span>$key</span> . " "<span>; </span><span> 9</span><span>$params</span>[":id_" . <span>$key</span>] = <span>$item</span>['id'<span>]; </span><span>10</span><span>$params</span>[":val_" . <span>$key</span>] = <span>$item</span>['val'<span>]; </span><span>11</span><span> } </span><span>12</span><span>$update_sql</span> .= "END WHERE id IN (:_ids)"<span>; </span><span>13</span><span>TEST::</span>execute(<span>$update_sql</span>, <span>$params</span>);//此处会调用bindParam绑定参数
後で、これが機能しないことがわかりましたが、奇妙なことに、これは可能です。最初のレコードのみを更新します。情報を調べたところ、このバインド方法は実行可能ではなく、IN ステートメントのパラメータを 1 つずつバインドする必要があることがわかりました。ドキュメント内のbindParam関数の説明を見てください:
この説明では、PHP変数がプレースホルダーにバインドされると書かれていることがわかります。そのため、IDが1と2の文字列がバインドされている場合、 MySQL がステートメントを解析するとき、1 と 2 を文字列として扱うのではなく、個々の変数に解析します。これは、SQL インジェクションを防ぐ PDO の原理でもあり、プレースホルダーのバインドを通じて、バインドされた値のみが値として扱われ、ステートメントなどの他の値は値として扱われません。 。
修正された記述:
<span> 1</span> <?<span>php </span><span> 2</span><span>$data</span> = <span>array</span>(<span>array</span>('id' => 1, 'val' => 2), <span>array</span>('id' => 2, 'val' => 3<span>)); </span><span> 3</span><span>$update_sql</span> = 'UPDATE tbl_test SET val = CASE id'<span>; </span><span> 4</span><span>$params</span> = <span>array</span><span>(); </span><span> 5</span><span>$params</span>[":ids"] = <span>$ids</span><span>; </span><span> 6</span><span>$in_arr</span> = <span>array</span><span>(); </span><span> 7</span><span> 8</span><span>foreach</span>(<span>$data</span><span>as</span><span>$key</span> => <span>$item</span><span>) { </span><span> 9</span><span>$update_sql</span> .= "WHEN :id_" . <span>$key</span> . "THEN :val_" . <span>$key</span> . " "<span>; </span><span>10</span><span>$params</span>[":id_" . <span>$key</span>] = <span>$item</span>['id'<span>]; </span><span>11</span><span>$params</span>[":val_" . <span>$key</span>] = <span>$item</span>['val'<span>]; </span><span>12</span><span>$params</span>[":ids_" . <span>$key</span>] = <span>$item</span>['id'<span>]; </span><span>13</span><span>array_push</span>(<span>$in_arr</span>, ":id_" . <span>$key</span><span>); </span><span>14</span><span> } </span><span>15</span><span>$update_sql</span> .= "END WHERE id IN (" . <span>implode</span>(',' <span>$in_arr</span>) . ")"<span>; </span><span>16</span> TEST::execute(<span>$update_sql</span>, <span>$params</span>);<span>//</span><span>此处会调用bindParam绑定参数</span>
概要
これは、私が最近遭遇した小さな問題です。実際、これは、MySQL の IN ステートメントでパラメーターを 1 つずつバインドする必要があることを説明するためのものです。
参考リンク:
mysql ステートメント: 複数のレコードの異なる値を一括更新
配列を IN() 条件にバインドできますか?
限られた書き方と浅い知識によるオリジナル記事 間違っている点があれば。記事内で、申し訳ありませんが、お知らせください。
この記事が役に立った場合は、おすすめをクリックしてください。記事を書くのは簡単ではありません。
上記では、PHP の PDO 拡張機能を使用して、php および PDO コンテンツを含むバッチ更新操作を実行する [PDO バインディング パラメーター] を紹介しました。PHP チュートリアルに興味のある友人に役立つことを願っています。

人気の記事

人気の記事

ホットな記事タグ

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド

PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法
