SQLではNULLの取り扱いに要注意

PHP, JavaScriptなど、いい感じにNULLを言語側で扱ってくれる言語を使っていると楽なのですが、

何となくで扱ってくれないSQLなどで、何となく扱ってしまうと痛い目を見ます。

(Oracleでは今のところNULLを0として扱ったりしてくれますが…)

今回は、何となくNULLを扱ってしまうことで起こる問題点と対応策を僕なりに書いてみようと思います。

NULLとは

大前提として、NULLとは何なのかをWikipediaから引用しつつ説明します。
(何を今さらと言われる内容なので分かっている方はスキップしていただければと思います。)

Null(ヌル、ナル)は、何もない、という意味で、プログラミング言語などコンピュータ関係では、「何も示さないもの」を表すのに使われる。しばしば zero または empty と交換可能である。

しばしば zero または empty と交換可能である。」と記載されていますが、

命題:「NULLは、常にzeroまたはemptyと交換可能である。」が正しくないことに注意が必要です。

zeroまたはempty感覚でNULLを扱ってしまうと、大変なことになります。

そもそもzeroは値ですが、NULLは値でありません。(時々、NULL値と呼ぶ人もいるようですが…)

NULLは、あくまで「何も示さないもの」を表すマーカーにすぎません。

もしNULLを値と勘違いしている人がいると、こんな感じのSQL文でも正しい結果が取得できそうと

考える人もいらっしゃるかもしれません。

SELECT 
    *
FROM
    TBL_SAMPLE
WHERE
    COL = NULL
;

※ NULLは値でなく、状態の一種なので比較述語を使うことができません。

第3の値 UNKNOWN

先ほどまでは、NULLが値でないことを念のため確認しました。

次は、先ほどのSQL文のWHERE句がどのように評価されるのかを説明していきたいと思います。

またまた前提知識として、SQLの世界には、UNKNOWN呼ばれるTRUEでもないし、

FALSEでもない状態があります。(UNKNOWNは、論理値の一種です。)

簡単に言葉で表すなら、未来時点ではTRUEに評価されることがあるかもしれませんが、

FALSEも評価される可能性があるので、現在時点では決まらないみたいな感じでしょうか。

実は先ほどのSQL文ではWHERE句がUNKNOWNと評価されてしまいます。
(NULLと比較述語を組み合わせると、UNKNOWNと無条件に評価されます。)

また、WHERE UNKNOWN は、WHERE FALSEと記述している事と変わらないように扱われますので、

正しい検索結果を取得することができませんでした。

本来ならUNKNOWNの説明と、何となくNULLを扱ってしまうことで起こる問題点と対応策を

もう少し書きたかったのですが、あまりにも長くなってしまいそうなので、

UNKNOWNの説明はWikipedia(クリーネの3論理値)を参考にしていただくこととして、

次回、問題点と対応策を書いてみようかと思います。

以上。