MySQL IN ステートメントの PDO バインディング値
PDO を使用して値の配列を MySQL IN にバインドするときに問題が発生します声明。目標は、次のようにクエリを実行することです:
SELECT users.id FROM users JOIN products ON products.user_id = users.id WHERE products IN (1,2,3,4,5,6,7,8)
ただし、PDO はバインドされた値をカンマ区切りの文字列に変換しているため、次のような誤ったクエリが生成されます:
SELECT users.id FROM users JOIN products ON products.user_id = users.id WHERE products IN ('1,2,3,4,5,6,7,8')
カスタム関数を使用してクエリ自体内のカンマ区切り文字列を分割しようとしましたが、これは最適ではありませんsolution.
解決策 1: クエリを手動で構築する
前の質問で提案したように、各 IN 句の値のプレースホルダーを連結することでクエリを手動で構築できます。例:
$products = array(1,2,3,4,5,6,7,8); $placeholders = array_fill(0, count($products), '?'); $sql = "SELECT users.id FROM users JOIN products ON products.user_id = users.id WHERE products IN (" . implode(',', $placeholders) . ")"; $stmt = $pdo->prepare($sql); $stmt->execute($products);
解決策 2: find_in_set() を使用する
find_in_set() 関数を使用して、値をカンマ区切りの文字列と照合できます。ただし、このアプローチでは、テーブル内のすべての値を文字型に変換する必要があるため、大規模なデータセットではパフォーマンスの問題が発生する可能性があります。
$products = array(1,2,3,4,5,6,7,8); $sql = "SELECT users.id FROM users JOIN products ON products.user_id = users.id WHERE find_in_set(cast(products.id as char), '" . implode(',', $products) . "') > 0"; $stmt = $pdo->prepare($sql); $stmt->execute();
解決策 3: ユーザー定義関数の作成
最良の解決策は、カンマ区切りの文字列を分割するユーザー定義関数 (UDF) を作成することです。これは比較的複雑なソリューションですが、可変サイズのリストを含む IN 句に最高のパフォーマンスを提供します。
UDF の作成手順については、提供されているリンクを参照してください。
以上がPDO を使用して配列値を MySQL IN ステートメントに適切にバインドする方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。