ホームページ  >  記事  >  バックエンド開発  >  [PDO バインディング パラメータ] PHP の PDO 拡張機能を使用してバッチ更新操作を実行します php pdo sqlite php pdo odbc php open pd

[PDO バインディング パラメータ] PHP の PDO 拡張機能を使用してバッチ更新操作を実行します php pdo sqlite php pdo odbc php open pd

WBOY
WBOYオリジナル
2016-07-29 08:52:301736ブラウズ

最近、データベース テーブルの特定のフィールドをバッチ更新するという要件があり、この要件を実行する際にパラメーターのバインドに 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 pdo中文手册,php pdo教程,php pdo mysql,php pdo.dll,php pdo mssql.dll,php pdo扩展,php pdo mysql.dll,php pdo.dll下载,php pdo mssql,php pdo类,php pdo mysql类,php pdo fetch,php pdo sqlite,php pdo odbc,php开启pd

この説明では、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 チュートリアルに興味のある友人に役立つことを願っています。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。