特別な値 NULL 値

オラクルにおける NULL とは、C言語などの NULL STRING '\0' CHAR(0) とは別の存在である。
また、数学の空集合(a set null) と比較すると宇宙の特異点のようなブラックホールとも思える強力なパワーで特別な振る舞いをする。
それを知らないでおくと、ブラックホールに飲み込まれて大切なデータを失う時限式の不具合を抱えることになりかねない。

NULL と論理演算

xyx AND yx OR y
TRUENULLNULLTRUE
FALSENULLFALSENULL
NULLNULLNULL

NOT NULL も NULL になる。

比較条件 と NULL

NULL はデータの欠落をあらわす、任意の値や別の NULL と等号や不等号は成立しない。
直接比較するには IS NULLIS NOT NULL を使用する。

  • NULL とWHERE 条件
val の値条件式検索の結果
10val IS NULLFALSE
'abc'FALSE
10val IS NOT NULLTRUE
'abc'TRUE
NULLval IS NULLTRUE
val IS NOT NULLFALSE
NULLval = NULLUNKNOWN
(TRUE でも FALSEで もない)
NOT val = NULL
NULLval = 10UNKNOWN
(TRUE でも FALSEで もない)
NOT val = 10
val <> 10
NOT val <> 10
val = 'abc'
NOT val = 'abc'
NULLval IN ( 1, 2, 3)
val NOT IN ( 1, 2, 3)
val IN ( NULL, 2, 3)
val NOT IN ( NULL, 2, 3)
val IN ( 'a', 'b', 'c')
val NOT IN ( 'a', 'b', 'c')
val IN ( NULL, 'b', 'c')
val NOT IN ( NULL, 'b', 'c')

NULL のソート ORDER BY NULLS 〜

Oracle 8.1.6 以上であれば、NULL の並べ替えのために NVL,MIN 関数を使う必要がなくなっている。
NULL はデフォルトの昇順ソートでは最後、降順ソートでは最初に並び替えられる。(≒無限大)

ORDER BY のオプション指定により、その並び順を変更することができる。

NULLS FIRST
NULL 値を順序の最初にするソートを行なう
NULLS LAST
NULL 値を順序の最後にするソートを行なう
例) ORDER BY ORDER_NO ASC NULLS FIRST

NULL の基本的な振る舞い

算術演算 と NULL

NULL を含む算術式はすべて NULL となる。

例) 1 + NULL ⇒ NULL
     NULL / 0 ⇒ NULL  ※ 0除算エラーにならない。

連結演算(||) と NULL

連結演算子は一方だけが NULL である場合は結果は NULL とならない。 2つのオペランドが NULL の場合には NULL となる。

例)SELECT FIRST_NAME || MIDDLE_NAME || LAST_NAME FROM "名簿"
     ⇒ '鈴木' + NULL + 'イチロウ' ⇒ 鈴木イチロウ

単一行ファンクション と NULL

NULL を引数とする、ほぼすべての単一行ファンクション(旧スカラーファンクション)は NULL が戻される。参考: 長さ0の文字の長さはゼロ?
但し、REPLACE、NVL、NVL2 、NULLIF、LNNVL、DECODE、COALESCE および CONCATを除く(他にもあるかもしれません)。

SELECT NVL(LENGTH(NULL),-1) LEN FROM DUAL ;
       LEN
----------
        -1

集計ファンクション と NULL

NULL を引数とする、ほぼすべての集計ファンクションは、NULL の行を無視(存在しないものと)する。
COUNT(*) は NULL も含む全件数を戻す。COUNT(カラム名)は、NULL を含まない件数を戻す。

SQL> COLUMN NUM NULL '<NULL>'
SQL> SELECT NUM FROM NUM_TEST ;
 
       NUM
----------
        10
<NULL>
        20
<NULL>
        30
<NULL>
        40
<NULL>
 
8行が選択されました。
 
SQL> SELECT
  2   SUM(NUM) "合計",
  3   AVG(NUM) "平均(NUM)", AVG(NVL(NUM, 0)) "平均(*)",
  4   COUNT(NUM) "件数(NUM)", COUNT(*) "件数(*)"
  5  FROM NUM_TEST ;
 
      合計  平均(NUM)    平均(*)  件数(NUM)    件数(*)
---------- ---------- ---------- ---------- ----------
       100         25       12.5          4          8

SQL*Plus の NULL 表示



副問い合わせのコーディングミスによる UPDATE での不具合

更新問い合わせに関する NULL の問題。 忘れた頃に、また思い出させるような事が続く問題です。 入門者がコレと対峙すると、簡単に脱出できません。

売上累計と売上明細に関する仮想問題 を参考にしてください。

日本オラクル
■ 日本オラクル 株式会社
■ オラクルマスター資格 (オラクルマスターとは
■ Oracle Web セミナー