2012-02-10 5 views
3

SET ANSI_NULLS OFFモードは非常に便利で、一貫して動作する場合はデフォルトで使用します - =または!= everywhereを使用してNULLを比較できるようにします。しかし、それは、明示的なインラインnullと比較する場合にのみ機能しますが、nullを含むフィールドと比較すると、動作しません。なぜマイクロソフトはそのように設計するのだろうか? 誰もデフォルトでSET ANSI_NULLS OFFモードを使用する理由は不思議ではありません。私はむしろ、私がインラインで使っているものと考えていないものを考えるより、 "ヌル"と "ヌルではない"という痛みを感じています。なぜフィールドの比較にANSI_NULLS OFFが機能しないのですか?

問題を示す例を以下に示します。 2行を返しますが、1行しか返しません。

CREATE TABLE t1 (a int null, b int null) 
INSERT INTO t1 values (null,null) 
INSERT INTO t1 values (0,null) 
INSERT INTO t1 values (null,0) 
INSERT INTO t1 values (0,0) 
set ansi_nulls ON 
select * from t1 where a=null -- empty result 
select * from t1 where a=b -- (0,0) 
select * from t1 where null=null -- empty result 
set ansi_nulls OFF 
select * from t1 where a=null -- (null,null),(null,0) 
select * from t1 where a=b -- why only (0,0) ???, it should be (0,0),(null,null) 
select * from t1 where null=null -- returns all 4 rows 
drop table t1 

答えて

6

これは、ここに答えた:

How does ANSI_NULLS work in TSQL?

セットは、オペランドの一方がnullの変数またはリテラルnullの場合のみ比較です影響を与えオフにANSI_NULLS。それは将来的にはサポートされませんよう

はまた、あなたが、オフの設定を使用して、新しいコードを書くべきではありません。

http://msdn.microsoft.com/en-us/library/ms188048.aspx

更新:

あなたの質問を再読み込みした後

、私はあなたが効果的に言っていると思う理由はない。このような

select * from t1 where a=b 

機能:

select * from t1 where a=b or (a=null and b=null) 

あなたの例で(null、null)、(0,0)を返します。

だから、あなたは二つの条件をチェックされています

  1. どちらの列の値が
  2. どちらの列の値が
  3. あなたの式は= nullのように書かれ

が、それは不明である等しいですあなたがしようとしていることはかなり明確です。しかし、a = bと書かれている場合は、第1の条件のみを調べるか、または両方をチェックするつもりですか?

別の方法として、同じ自宅+携帯電話番号を持つすべての顧客を返すクエリを作成しているとします。これらの列の両方にnull値を持つ顧客を戻したいですか?

要するに、MSFTでは、1つしか記載されていない場合、自動的に2つの条件をチェックしたくない - これは正しいデザインだと思う。

+3

OPはどのように動作するのかを知っています。彼らは**そのように実装された理由を尋ねています**。 –

+0

@Brian Vander Plaats:== bを置くと、SQLよりもはるかに優れた設計がされたJavaScript(MSFTが設計していない言語)では、==未定義、b ==未定義であっても真です。なぜSQLはJavaScriptと異なる必要がありますか? – alpav

+0

@alpav C#でも同様に、null == nullがtrueであることに注意してください。私はMSFTがこのようにSQL Serverで動くことができたと思いますが、これは標準に準拠していません。 3VLセクション:http://en.wikipediaを参照してください。org/wiki/SQL –

関連する問題