- - PR -
SQLの IS NULL , IS NOT NULLの歴史的経緯?
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 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するときに必要) など、わかる方がいたら教えてください。 | ||||
|
投稿日時: 2004-05-07 23:14
歴史的経緯?は、わからないのですが、
NULLと何かを演算したら、NULLになるので、 比較演算の結果もNULLになってしまうのでは? | ||||
|
投稿日時: 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 にしないほうがいいです) | ||||
|
投稿日時: 2004-05-07 23:53
はにまるです。
言われて見ると、そうですね。なぜ、IS [NOT] NULL なんでしょうね? 僕も歴史的背景はわかりませんが、コンピュータの内部処理で考えると。 (ここから全て妄想で言っています、ご存知の方、お願いします) そもそも、「=」というのは、比較する2つの値(ビット)をXOR演算子で 処理した結果がALL0の時を示すのでは無いでしょうか?(本当に?)
「何故、Nullは上記の考えで駄目のか?」となる訳ですが、 これまた妄想ですが、Nullは何がしかの値を持つ必要が無い為、 DBMSがデータ取得時に値なしと判断し、xor演算の条件処理まで到達出来ないから、 と考えます。 解り易い説明にし直しますね。 「テキストファイルA」に記述された値と「テキストファイルB」に記述された値を 比較すると考えましょう。 1.= もしくは <> が指定されたら、そのまま、ファイルを読んで値の比較判断をします。 2.上記1の処理でファイルが無い(比較値のどちらかがNULL)場合は、 エラー(つまり、NULLを返す)です。 3.IS [NOT] NULL が指定されている場合、ファイルの存在チェックのみ行います。 つまり、値比較する処理(=、<>)か、存在チェック処理(IN [NOT] NULL)かの 違いだと思います。 # 念の為、追記です。 それらしい理由で述べていますが、xorの話も含め妄想で言っていますからね。 [ メッセージ編集済み 編集者: はにまる 編集日時 2004-05-07 23:59 ] | ||||
|
投稿日時: 2004-05-08 00:05
unibon です。こんにちわ。
いわゆる「3値論理」だからです。私の個人的な見解ですが、このような論理は、使いにくいし分かりにくいし、とてもキレイだとは思えないのですが、SQL が登場した昔はキレイに見えたのではないでしょうか。
ある言語(Java や C# や VB や Perl やその他種々の言語)の実行により、別の言語(SQL)を生成するので、多少の不便はしかたがないとは思います。ただ、やりにくいのはたしかですね。 今後も RDBMS は使い続けるにしても、アクセスするための言語が SQL であることに拘る必要性はそんなにないのではと思います。SQL に代わる現代風の言語があっても良いと思うのですが、その兆しってあるのでしょうか。 | ||||
|
投稿日時: 2004-05-08 01:50
私も確信を持っているわけでもないですが...
確か、データベースでのNullというのは、値そのものが無いということじゃ 無くて、Nullビット(だったかNullフラグだったか?)が立っている状態を 表すということだったかと思います。 この意味で区別しているようにも思うのですが... | ||||
|
投稿日時: 2004-05-08 22:51
余談ですが、私はVBプログラマー上がりなので、
「Nullとの比較は xxx is Null と書くのが普通だ」と思ってました。 Javaを始めてビックリ・・・ | ||||
|
投稿日時: 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の参照はここですよ〜と一意に決めてるんじゃないでしょうか。 #なので == 参照の比較が可能なのだと思います。 |