質問: $pdo->prepare("SELECT * FROM table WHERE 分類=?"); ``` といった具合に、複数のプリペアドステートメントを用意しています。 いまは分類と色という2つの検索条件しかありませんが、今後もっと増えていくことを考えると、 (2^検索条件数-1)個のプリペアドステートメントを用意しないといけなくなります。 それでは管理が大変になるのでナントカしたいです。 どのようにするのが良いでしょうか。 よろしくお願いいたします。
回答: 何かの雑誌に、以下のようなテクニックが紹介されていました。 例えば 「バインドするパラメータが NULL であれば、検索条件に含めない」 ことが決まっているなら、以下のようなSQL文を用意します。 ``` $stmt = $pdo->prepare(' SELECT * FROM table WHERE (`分類` = :category OR :category IS NULL) AND (`色` = :coler OR :coler IS NULL) '); // PDO::PARAM_INT 部分は、実際の型に合わせる $stmt->bindValue(':category', $category, is_null($category) ? PDO::PARAM_NULL : PDO::PARAM_INT); $stmt->bindValue(':coler', $coler, is_null($coler) ? PDO::PARAM_NULL : PDO::PARAM_INT); ``` こうしておけば、例えば`$category = null`の場合、パラメータをバインドした後のSQL文は ``` SELECT * FROM table WHERE (`分類` = NULL OR NULL IS NULL) AND (`色` = ? OR ? IS NULL) ``` となり、実質、'分類'カラムに対する検索条件を指定しなかったことと同じ意味になります。 一応、私が手元の環境 (CentOS6.5, MySQL5.6) で簡単に検証した限りでは、インデックスも正常に使用できました(※)が、これに関しては、必ずご自分の環境で確かめてみてください。 ※おそらく、`OR ? IS NULL`という条件には「定数条件の削除」という最適化が働くためと推測します