• 締切済み

PDO で IN句を利用することができません

PDOでIN句を使用しているのですが、正しく動作しません。 $stmt = $pdo->prepare('SELECT * FROM hoge where id in (?)'); $stmt->bindValue(1, '123, 456, 789'); $stmt->execute(); var_dump($stmt->fetchAll()); fetchAllを行っても複数のレコードがかえってこず、ヒットした最初の1行のレコードしか取得することができません。PDOでIN句を使用することはできないのでしょうか? DBMSはMySQLを使用して、PHPは5.2.6を使用しています。 ちなみに $stmt = $pdo->prepare('SELECT * FROM hoge where id in (?, ?, ?)'); $stmt->bindValue(1, 123); $stmt->bindValue(2, 456); $stmt->bindValue(3, 789); $stmt->execute(); では、fetchAll で複数のレコードが返ってきます。 どうしてもpreparedで単一のIN句を使いたいのですが、何か良い方法はありますでしょうか?

みんなの回答

  • masa6272
  • ベストアンサー率66% (93/140)
回答No.1

もし、? にバインドする3つの値が、ユーザーの入力と無関係で、SQLインジェクションの危険がないのなら、 直接 $stmt = $pdo->query('SELECT * FROM hoge where id in (123,456,789)'); で実行すればいいと思います。 ?を使って書くのは、SQLインジェクション対策です。prepareで、構文解析を行い、実行プランを立てます。この段階で、?にはスカラー値しか入らないようになっています。ユーザーが変な値をフォームから入れても、ここには構造を持たないスカラーしか入れられません。 最初の例のように、bindしても?には'123,456,789'という文字列がbindされます。 SELECT * FROM hoge where id in ('123,456,789') 本来、これはデータ型の不一致ではじく方がいいと思いますが、MySQLはSQLとしてはデータ型に寛容ですので、idが整数の123の時は、動いてしまいます。'123,456,789'を整数として評価して、123と見ます。 つまり、 SELECT * FROM hoge where id in (123) と考えます。結果として、idが123の行が返ります。

noname#200773
質問者

お礼

ありがとうございました。 どうやらマニュアルにもかかれているようで、まとめてIN句に指定することができないみたいでした。 http://jp2.php.net/manual/ja/pdo.prepare.php このことから、事前にSQLを組み立てる際に、IN句に利用する値は IN(?, ?, ?) に展開して prepare するようにします。

関連するQ&A