PHP
MySQL
PDO
データベース

プレースホルダで「= ?」と「IS NULL」に同時に対応する方法

More than 3 years have passed since last update.


こんなとき、あなたならどうする?

プレースホルダにバインドされる値が 文字列NULL の2通りあって、どちらにも対応してSQLを発行しなければならないとき。

これらのケースは動作します。

SELECT * FROM test WHERE hoge = 'yeah'

SELECT * FROM test WHERE hoge IS NULL

ところがこれらは動作しません。

SELECT * FROM test WHERE hoge IS 'yeah'

SELECT * FROM test WHERE hoge = NULL

さてどうしましょう?


解決策1

プリペアドステートメントの生成時点で場合分けすればOK。

$array = array('yeah', null);

$value = $array[array_rand($array)];

$holder = $value === null ? 'IS NULL' : '= ?';
$stmt = $pdo->prepare("SELECT * FROM test WHERE hoge {$holder}");
$value === null ? $stmt->execute() : $stmt->execute(array($value));


解決策2

spaceship (宇宙船) っていうカッコイイ名前の演算子があるようです。

ss (2013-12-20 at 04.01.19).png

MySQLマニュアル を見てみると・・・

ss (2013-12-20 at 04.00.20).png

NULL-Safe だって!これはもう使うしかない!

$array = array('yeah', null);

$value = $array[array_rand($array)];

$stmt = $pdo->prepare("SELECT * FROM test WHERE hoge <=> ?");
$stmt->bindValue(1, $value, $value === null ? PDO::PARAM_NULL : PDO::PARAM_STR);
$stmt->execute();

これいいですね・・・!