foldrr's weblog

旧ブログ http://d.hatena.ne.jp/foldrr/

MySQL でパラメータライズドクエリのパラメータを IS NULL で比較した場合の環境による挙動の違い

照会画面でチェックボックスを使った検索条件があり、テーブルの該当カラムに NOT NULL 制約が付いていない場合は、SQL の WHERE 句を工夫する必要がある。
※NOT NULL 制約付けなよ!というのはさておき…。

SELECT *
  FROM SOME_TABLE T
 WHERE T.COL1 = :PARAM1 OR (:PARAM1 IS NULL AND COL1 IS NULL)


文字列を組み立ててもいいが上記のようなことをやりたいケースが多い。
それで、":PARAM IS NULL" の部分でハマった。
環境によって挙動が違った。

現象

PHP で以下のパラメータライズドクエリを利用すると、
結果は環境によって異なる。

SELECT *
  FROM SOME_TABLE
 WHERE :PARAM1 IS NULL  -- :PARAM1 に PHP の null をセットする

原因

不明です。
実際のSQL実行までの経路にある以下が関係していると思われる。

  • PHP(PDO)の実装の違い
  • MySQLの設定の違い

対策

IS NULL 述語を使わずに空文字と比較する。
先ほどのコードを書き換えると以下になる。

SELECT *
  FROM SOME_TABLE
 WHERE T.COL1 = :PARAM1 OR (:PARAM1 IS NULL AND COL1 IS NULL)