Bir tabloda NULL değer kendi kendine karşılaştırma


13

Aşağıdaki gibi bazı gizemli t-sql davranışları hakkında her zaman şaşkınım

-- 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 

Bu, tablodaki tüm satırların nasıl alınacağı ve ANSI_NULLS kullanımından kaçınmakla ilgili değildir.

Sadece t-sql'ın neden böyle davrandığını anlamak istiyorum.

Yanıtlar:


13

Bu şaşırtıcı bir davranış ancak MSDN sayfasından, SET ANSI_NULLSen azından beklenen davranış olduğunu biliyoruz. Asla kullanmamak için bir neden daha ANSI_NULLS OFF:

SET ANSI_NULLSkarşılaştırmayı yalnızca karşılaştırmanın işlenenlerinden biri ya değişken NULLya da değişmezse etkiler NULL. Karşılaştırmanın her iki tarafı sütun veya bileşik ifadelerse, ayar karşılaştırmayı etkilemez.


8

Msdn dokümantasyonundan çok net olmasa da, aşağıdakileri doğru bulacağınıza inanıyorum

"SET ANSI_NULLS ON bir karşılaştırmayı yalnızca karşılaştırmanın işlenenlerinden biri NULL veya değişmez bir NULL ise etkiler. Karşılaştırmanın her iki tarafı da sütun veya bileşik ifadeler ise, ayar karşılaştırmayı etkilemez."

Bkz. Https://stackoverflow.com/questions/2866714/how-does-ansi-nulls-work-in-tsql


Teşekkürler Scott ve ypercube, her iki yanıtı bu davranış için puan, bu yüzden her iki yanıtı vekil.
jyao

Ypercube ilk oldu :)
Scott

4

Robert Sheldon, 2015'in sonraki gönderisinde NULL davranışları ve neden bazen (ama her zaman değil) başarısız olduklarını tartışıyor

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

Bir programcının kolayca atlayabileceği 13 NULL hatası açıklar.

Hata # 1: NULL'un ne anlama geldiğini bilmemek

Açıklama: NULL değer olmayan, var olmayan bir değerdir. Sıfır değil. Boş bir dize değil. Bir değer NULL değerine eşit olamaz. İki NULL değer eşit değildir .

Temel sorun budur, ancak diğer arızaları okuduğunuzdan emin olun.

Evet, önceki sürümler (SQL Server 7 öncesi inandığım) daha çok istediğiniz gibi davrandılar.

Ancak, Stack Overflow ve Stack Exchange'de sorunu ararsanız, sorunları tartışan birçok uzun konu bulacaksınız.


3
Bir keresinde Robert Sheldon'ın bağlantılı gönderisini okudum, ancak (IMHO) örneğimin davranışını açıklayan herhangi bir teori veya kanıt yok.
jyao

1
Msgstr "Hiçbir iki NULL değer eşit değil." Tamam ama bilen insanlar bile ansi nulls kapalı olduğunda tam tersi beklenir. Özellikle WHERE NULL = NULLayar ayarlandığında verim doğru olduğundan.
ypercubeᵀᴹ

1

Tartışmaya eklemek için, SQL92 standardının NULL tanımı belirsiz bir şekilde yorumlanabilir. Burada , sqlite.org'un izniyle çeşitli DBMS'lerden NULL kullanım ve yorumlamanın iyi bir özeti verilmiştir.

AÇIKLAMA : Yukarıda sqlite.org sayfasının eski bir sürümünden (6-8 yıl önce olduğu gibi) SQL92'nin "belirsizliği" hakkında bir şeyler okuduğumu hatırlıyorum, ancak bu sayfa o zamandan beri güncellendi.

Yukarıdaki RLF cevabı iyi teklifi var ama Robert Sheldon kabul etmezsem (yani, bir "var olmayan bir şeyi" düşünün çünkü sadece var NULL ) felsefi olmak ve İngilizce dil-anlamsal bir şey "eşdeğer başka biri yok ". Ben Sheldon'ın mantığını anlamak bensem sonra bir NULL tanımıdır olduğuna dair karar da BOŞ. (Eğer mevcut değilse, nasıl tanımlayabiliriz? Ürpertici, ha?)

Russell'ın Paradoks demlemesinin ( ve baş ağrısının) bir varyasyonunu görüyorum . : - \

Ama yine, bu İngilizce dil anlambilimiyle ilgili bir tartışma ( SQL DEĞİL ) ve felsefe tartışması buraya ait . :-)


PS: Bu SE topluluğunda yeniyim; Eğer bu daha önce müzede tartışılmışsa , özür dilerim.
pr1268

1
Standarttaki belirsizlik tam olarak nerede?
ypercubeᵀᴹ

@ ypercubeᵀᴹ: Belirsizliğin bir 3VL'yi bir Boole'ye "uydurma" girişiminde yattığına inanıyorum . NULL karşılaştırmalı tablo birleşimleri birkaç farklı şekilde yorumlanabilir.
pr1268

Tutarsızlık konusunda anlaşırdım, ancak belirsizlik konusunda değil.
ypercubeᵀᴹ

1
@ ypercubeᵀᴹ: Yeterince adil ... Sadece yukarıda bağladığım sqlite.org sayfasının daha eski bir versiyonunun söylediklerinden bahsediyordum ("SQL92, NULL kullanım ve yorumlama konusunda belirsizdir" ya da çok benzer bir şey). Ama tartışmak istemiyorum. Belki sqlite.org sayfasının kendisi yanıltıcı ve / veya hepsi yanlıştı. Hangi muhtemelen güncellenmiş olduğunu açıklar.
pr1268
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.