- PR -

SQLの IS NULL , IS NOT NULLの歴史的経緯?

投稿者投稿内容
platini
大ベテラン
会議室デビュー日: 2002/12/03
投稿数: 193
投稿日時: 2004-05-07 23:04
今年からプログラムに取り組んだ新人君にSQLを
教えている過程で、改めてあれっと思いました。

SQLの文法では WHERE aaa IS NULL あるいは IS NOT NULL
と書きますよね。

何で、 aaa = NULL あるいは aaa <> NULL
ではなく、こうなったのでしょうか?
恐らく、初期の規定作成過程で何らかの意図
(あるいは、実装上の問題?)でこうなったのだと思いますが・・・。

直接、自分でSQLを打ち込むときは IS だろうが、 = だろうが
どうでもよいのですが、
列の個数、検索対象列を動的にプログラム内部で
文字列としてSQLを動的生成するときのロジックが、
NULL値のときだけ
 IS あるいは IS NOT にしなくてはいけないので、
非常に面倒だと感じています。

もし、歴史的経緯あるいは実装上の問題(SQLをDBMSがParseするときに必要)
など、わかる方がいたら教えてください。
もぐ
会議室デビュー日: 2002/12/06
投稿数: 13
投稿日時: 2004-05-07 23:14
歴史的経緯?は、わからないのですが、
NULLと何かを演算したら、NULLになるので、
比較演算の結果もNULLになってしまうのでは?
よねだ
常連さん
会議室デビュー日: 2002/10/13
投稿数: 22
投稿日時: 2004-05-07 23:25
 米田です。

>SQLの文法では WHERE aaa IS NULL あるいは IS NOT NULL
>何で、 aaa = NULL あるいは aaa <> NULL
 原則から説明すると、
NULL は特定の(一つの)値とはいえないので、NULL と NULL が一致するわけではない
(かもしれない)からです。
 NULL は 不定とか UNKNOWN がイメージでしょうか。

 SQL Server 2000 Books Online の説明では、
>SQL-92 標準では、NULL 値に対して = (等号) 比較演算または <> (不等号) 比較演算
>を実行した場合、結果が FALSE になることが要求されています。
とのことです。
 このあたりは SQL-92 規格がからむので、古いバージョンや オプションで
aaa = NULL が使える状態もあります。
SQL Server 2000 では、
SET ANSI_NULLS OFF
としていると、 aaa = NULL を通すことが出来ます。
(ただし、機能面で制約につながりますので、OFF にしないほうがいいです)

はにまる
ぬし
会議室デビュー日: 2003/12/19
投稿数: 969
お住まい・勤務地: 誤字脱字の国
投稿日時: 2004-05-07 23:53
はにまるです。

 言われて見ると、そうですね。なぜ、IS [NOT] NULL なんでしょうね?

 僕も歴史的背景はわかりませんが、コンピュータの内部処理で考えると。

 (ここから全て妄想で言っています、ご存知の方、お願いします)

 そもそも、「=」というのは、比較する2つの値(ビット)をXOR演算子で
 処理した結果がALL0の時を示すのでは無いでしょうか?(本当に?)

コード:
 

 例
   1.'AB' = 'AB'

      ↓(アスキーコードに変換

   2.&h4142 = &h414142

      ↓(xor演算

      0100.0001.0010.0010
   3.xor)0100.0001.0010.0010
     -----------------------
      0000.0000.0000.0000 ←(一致)


 
 「何故、Nullは上記の考えで駄目のか?」となる訳ですが、
 これまた妄想ですが、Nullは何がしかの値を持つ必要が無い為、
 DBMSがデータ取得時に値なしと判断し、xor演算の条件処理まで到達出来ないから、
 と考えます。

 解り易い説明にし直しますね。

 「テキストファイルA」に記述された値と「テキストファイルB」に記述された値を
 比較すると考えましょう。

 1.= もしくは <> が指定されたら、そのまま、ファイルを読んで値の比較判断をします。
 2.上記1の処理でファイルが無い(比較値のどちらかがNULL)場合は、
   エラー(つまり、NULLを返す)です。
 3.IS [NOT] NULL が指定されている場合、ファイルの存在チェックのみ行います。

 つまり、値比較する処理(=、<>)か、存在チェック処理(IN [NOT] NULL)かの
違いだと思います。

# 念の為、追記です。
 それらしい理由で述べていますが、xorの話も含め妄想で言っていますからね。


[ メッセージ編集済み 編集者: はにまる 編集日時 2004-05-07 23:59 ]
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2004-05-08 00:05
unibon です。こんにちわ。

いわゆる「3値論理」だからです。私の個人的な見解ですが、このような論理は、使いにくいし分かりにくいし、とてもキレイだとは思えないのですが、SQL が登場した昔はキレイに見えたのではないでしょうか。

引用:

platiniさんの書き込み (2004-05-07 23:04) より:
直接、自分でSQLを打ち込むときは IS だろうが、 = だろうが
どうでもよいのですが、
列の個数、検索対象列を動的にプログラム内部で
文字列としてSQLを動的生成するときのロジックが、
NULL値のときだけ
 IS あるいは IS NOT にしなくてはいけないので、
非常に面倒だと感じています。


ある言語(Java や C# や VB や Perl やその他種々の言語)の実行により、別の言語(SQL)を生成するので、多少の不便はしかたがないとは思います。ただ、やりにくいのはたしかですね。
今後も RDBMS は使い続けるにしても、アクセスするための言語が SQL であることに拘る必要性はそんなにないのではと思います。SQL に代わる現代風の言語があっても良いと思うのですが、その兆しってあるのでしょうか。
Beatle
ぬし
会議室デビュー日: 2003/06/09
投稿数: 394
投稿日時: 2004-05-08 01:50
私も確信を持っているわけでもないですが...

確か、データベースでのNullというのは、値そのものが無いということじゃ
無くて、Nullビット(だったかNullフラグだったか?)が立っている状態を
表すということだったかと思います。

この意味で区別しているようにも思うのですが...
Cluster
ぬし
会議室デビュー日: 2003/03/06
投稿数: 289
お住まい・勤務地: 大阪
投稿日時: 2004-05-08 22:51
余談ですが、私はVBプログラマー上がりなので、
「Nullとの比較は xxx is Null と書くのが普通だ」と思ってました。
Javaを始めてビックリ・・・
tak3
ベテラン
会議室デビュー日: 2004/04/15
投稿数: 80
お住まい・勤務地: 菜の花・銀杏
投稿日時: 2004-05-09 06:41
おはようございます。
昼間に寝てたので、眠れないまま朝になってしまいました・・・

で、NULLについてですが
私も多分に想像ですが・・・

・値の比較は、比較演算子を使う。
・NULLは値でなく不定を表す概念である。
・NULLは値でないので、値の比較でなく存在チェックを行うことしかできない(値比較の場合、falseになる)

NULLを不定値という言葉で置き換えてみます。

1.A = 不定値(Aと不定値は同じ値ですか?)
2.A is 不定値(Aは不定値ですか?)

2の場合は、Aが不定値ならば、trueですし、そうでなければfalseですよね。
1の場合に、Aが不定値のときに、「不定値と不定値は同じ値ですか?」に置き換えます。

前者の不定値が後者の不定値と同じ値になることもあると思いますが、
概念的にいえば、常にfalseと考えるのが正しいのでは?
Aが不定値でなく、ある値としても上記と同様。
ということでNULLとの比較ができないので、IS NULLがあるのではないでしょうか。

#javaは、オブジェクトの初期値がNULLと決まっています。
#たぶん、JavaVMがNULLの参照はここですよ〜と一意に決めてるんじゃないでしょうか。
#なので == 参照の比較が可能なのだと思います。

スキルアップ/キャリアアップ(JOB@IT)