2017/12/07
プログラマを何かと悩ませるNULL、扱いを誤ったために障害となることもあります。
そして、ORACLEにおいてもNULLは存在し、動作仕様に注意が必要です。
本記事では、この悩ましいNULLの動作仕様について、まとめました。
sponsored link
ORACLEにおけるNULL
ORACLEを始めとするデータベースのNULLは、その項目がカラであることを指します。
具体的には、以下の2つのパターンでNULLとして設定します。
未知/不明…例.性別がよく分からない個人客の顧客マスタの性別項目
適用不能/非存在…例.法人客の顧客マスタの性別項目
いずれしろ、そのNULLの取り扱いには注意が必要になります。
NULLの取り扱いで注意すべき点
比較する際に、通常の比較演算子が使えない
比較を行う際に通常であれば、等しいかどうかを検査する際は【=】を使用しますし、等しくないかどうかを検査する際は【<>】や【!=】を使用します。
しかし、NULLを上記で比較するとUNKNOWN(不明)となり対象外となります。
NULLかどうかを検査する場合には【IS NULL】を使用し、NULL以外かどうかを検査する場合には【IS NOT NULL】を使用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
A ----- 11111 …① 22222 …② NULL …③ SELECT a FROM test_table WHERE a = NULL; ⇒対象なし SELECT a FROM test_table WHERE a <> NULL; ⇒対象なし SELECT a FROM test_table WHERE a IS NULL; ⇒③が抽出 SELECT a FROM test_table WHERE a IS NOT NULL; ⇒①と②が抽出 |
インデックスが効かない
上記のようにWHERE句でNULLかどうか評価した場合、インデックスが効きません。
それはインデックスは、NULL以外のデータを対象として構成されているためです。
1 2 3 4 5 |
SELECT a FROM test_table WHERE a = '11111'; ⇒インデックスは有効 SELECT a FROM test_table WHERE a IS NULL; ⇒インデックスは使えない |
演算で結果がNULLになる
NULLが一部に含まれた演算を行うと、結果もNULLになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
SELECT a ,b ,a + b calc1 ,a - b calc2 ,a * b calc3 ,a / b calc4 FROM test_table ; -- 検索結果(NULLは【NULL】と表現) A B CALC1 CALC2 CALC3 CALC4 ----- ----- ----- ----- ----- ----- 6 2 8 6 12 3 6 NULL NULL NULL NULL NULL NULL 2 NULL NULL NULL NULL NULL 0 NULL NULL NULL NULL ← ゼロ割エラーも発生しない |
標準関数の戻り値が想定と異なることも
ORACLEの標準関数も、NULLが引数で渡した際に、関数によって動作が異なるので、想定と異なってしまうことが考えられます。
例えば、文字列の長さを戻すLENGTHは、引数としてNULLを渡すとNULLを戻します。(0ではない)
また、文字列を連結するCONCATは、2つの引数が両方ともNULLの場合はNULLを戻しますが、どちらか一方がNULL以外の場合は、その値を戻します。
1 2 3 4 5 6 7 8 9 10 |
SELECT a ,LENGTH(a) func FROM test_table ; -- 検索結果(NULLは【NULL】と表現) A FUNC ------ ----- ABCDE 5 NULL NULL |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
SELECT a ,b ,CONCAT(a,b) func FROM test_table ; -- 検索結果(NULLは【NULL】と表現) A B FUNC ----- ----- ------ ABC DEF ABCDEF NULL DEF DEF ABC NULL ABC NULL NULL NULL |
まとめ
悩ましいNULLの動作仕様について、細かく見てきました。
比較の際に【IS NULL】を使用しなければならないと知っている方も多いと思います。
しかし、本来NULLは入らないはずなので考慮しなかったことで障害となったり、インデックスが効かないことを知らなかったためにパフォーマンス障害となったりすることは、よく聞きます。
NULLの取り扱い、注意しましょう。
関連