テーブル内のNULL値の自己比較


13

次のような不思議なt-sqlの振る舞いについて私はいつも困惑しています

-- Create table t and insert values.  
use tempdb
CREATE TABLE dbo.t (a INT NULL);  
-- insert 3 values
INSERT INTO dbo.t values (NULL),(0),(1);  
GO  
set ansi_nulls off -- purposely turn off, so we can allow NULL comparison, such as null = null
go
-- expect 3 rows returned but only 2 returned (without null value row)
select * from dbo.t where a = a 

これは、テーブル内のすべての行を取得する方法ではなく、ANSI_NULLSの使用を避けることでもありません。

t-sqlがこのように動作する理由について、いくつかの洞察を求めたいと思います。

回答:


13

これは驚くべき動作ですが、MSDNページからSET ANSI_NULLS、少なくともそれが予想される動作であることがわかります。使用しないもう1つの理由ANSI_NULLS OFF

SET ANSI_NULLS比較のオペランドの1つがである変数NULLまたはリテラルで ある場合にのみ、比較に影響しますNULL比較の両側が列または複合式である場合、設定は比較に影響しません。


8

msdnのドキュメントからは明確ではないかもしれませんが、次のことが真実だと思います

「比較のオペランドの1つがNULLまたはリテラルNULLである場合にのみ、SET ANSI_NULLS ONは比較に影響します。比較の両側が列または複合式である場合、設定は比較に影響しません。」

これを参照してください/programming/2866714/how-does-ansi-nulls-work-in-tsql


スコットとypercubeに感謝します。あなたの答えはどちらもこの振る舞いの要点ですので、私はあなたの両方の答えに賛成です。
チャオ

Ypercubeが最初でした:)
スコット

4

2015年の次の投稿のRobert Sheldonは、NULL動作と、それらが時々(常にではないが)失敗する理由について説明しています。

https://www.simple-talk.com/sql/t-sql-programming/how-to-get-nulls-horribly-wrong-in-sql-server/

彼は、プログラマーが簡単にトリップできる13個のNULL障害について説明しています。

失敗#1:NULLの意味がわからない

説明:NULLは値ではなく、存在しない値です。ゼロではありません。空の文字列ではありません。値をNULLと等しくすることはできません。等しい2つのNULL値はありません

それが基本的な問題ですが、他の障害についても必ず読んでください。

はい、以前のバージョン(SQL Server 7以前のバージョン)は異なる動作をし、望みどおりに動作しました。

ただし、Stack OverflowとStack Exchangeで問題を検索すると、問題を議論している多くの長いスレッドが見つかります。


3
ロバート・シェルドンからリンクされた投稿を読んだことがありますが、(IMHO)には私の例の振る舞いを説明する理論や証拠がありません。
チャオ

1
「等しい2つのNULL値はありません。」わかりましたが、それを知っている人でさえ、ansi nullがオフに設定されていると反対のことを期待するでしょう。特にWHERE NULL = NULL、設定が正しい場合にtrueが生成されるためです。
ypercubeᵀᴹ

1

議論に追加するには、SQL92標準のNULLの定義を曖昧に解釈できます。以下は、sqlite.orgの好意によるさまざまなDBMSからのNULL処理と解釈の概要です

開示:上記リンクのsqlite.orgページの古いバージョン(6〜8年前など)からSQL92の「あいまいさ」について読んだことを覚えていますが、そのページは更新されています。

上記のRLFの答えは良い引用符を持っていますが、私はロバート・シェルドンに同意できない場合、それは私が「存在しないもの」(すなわち考えるだけの理由だNULL哲学と英語、意味的なもの「に相当する)他に存在しません。 「。私はシェルドンのロジックを理解することだ場合、その一つがNULLの定義は宣言する可能性があり、また NULL。(それが存在しない場合、どのように定義できますか?不気味ですよね?)

ラッセルのパラドックス醸造バリエーション(および頭痛)が見えます。:-\

しかし、これも英語のセマンティクスNOT SQL)に関する議論であり、哲学の議論はここにあります。:-)


PSこのSEコミュニティは初めてです。これが前に広告の吐き気について議論された場合、私は謝罪します。
pr1268

1
標準のあいまいさは正確にどこにありますか?
ypercubeᵀᴹ

@ypercubeᵀᴹ:あいまいさは、3VLをブール値に「適合」させる試みにあると考えています。NULL比較使用したテーブル結合は、いくつかの異なる方法で解釈できます。
pr1268

矛盾については同意しますが、あいまいさについては同意しません。
ypercubeᵀᴹ

1
@ypercubeᵀᴹ:結構です...私は上記でリンクしたsqlite.orgページの古いバージョンが言ったことを引用していました(「SQL92はNULLの処理と解釈に関してあいまいです」または非常に似ています)。しかし、私は議論するつもりはありません。おそらく、sqlite.orgページ自体が誤解を招いていたり、不正確だったりしていました。おそらく更新された理由を説明しています。
pr1268
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.