NULL membandingkan nilai sendiri dalam sebuah tabel

13

Saya selalu bingung tentang beberapa perilaku misterius t-sql, seperti yang berikut ini

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

Ini bukan tentang cara mengambil semua baris dalam tabel dan juga bukan tentang menghindari penggunaan ANSI_NULLS.

Saya hanya ingin meminta beberapa wawasan mengapa t-sql berperilaku seperti ini.

jyao
sumber

Jawaban:

13

Ini adalah perilaku yang mengejutkan tetapi dari halaman MSDN SET ANSI_NULLS,, kita setidaknya bisa tahu bahwa itu perilaku yang diharapkan. Satu lagi alasan untuk tidak pernah menggunakan ANSI_NULLS OFF:

SET ANSI_NULLSmempengaruhi perbandingan hanya jika salah satu operan perbandingannya adalah variabel yang NULLatau literal NULL. Jika kedua sisi perbandingan adalah kolom atau ekspresi majemuk, pengaturan tidak mempengaruhi perbandingan.

ypercubeᵀᴹ
sumber
8

Meskipun mungkin tidak jelas dari dokumentasi msdn, saya yakin Anda akan menemukan yang berikut ini benar

"SET ANSI_NULLS ON memengaruhi perbandingan hanya jika salah satu operan perbandingannya adalah variabel NULL atau NULL literal. Jika kedua sisi perbandingan adalah kolom atau ekspresi majemuk, pengaturan tidak mempengaruhi perbandingan."

Lihat ini /programming/2866714/how-does-ansi-nulls-work-in-tsql

Scott Hodgin
sumber
Terima kasih Scott dan ypercube, kedua jawaban Anda adalah poin untuk perilaku ini, jadi saya membesarkan kedua jawaban Anda.
jyao
Ypercube adalah yang pertama :)
Scott Hodgin
4

Robert Sheldon dalam posting berikut dari tahun 2015 membahas perilaku NULL dan mengapa mereka kadang-kadang (tetapi tidak selalu) gagal

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

Dia menjelaskan 13 kegagalan NULL yang mudah dialami oleh seorang programmer

Kegagalan # 1: Tidak tahu apa arti NULL

Penjelasan: NULL adalah nilai yang tidak ada, nilai yang tidak ada. Bukan nol. Ini bukan string kosong. Nilai tidak boleh sama dengan NULL. Tidak ada dua nilai NULL yang sama .

Itu adalah masalah mendasar, tetapi pastikan untuk membaca tentang kegagalan lainnya.

Ya, versi sebelumnya (pra-SQL Server 7 saya percaya) berperilaku berbeda, lebih seperti apa yang Anda inginkan.

Namun, jika Anda mencari masalah di Stack Overflow dan Stack Exchange Anda akan menemukan banyak utas panjang yang membahas masalah tersebut.

RLF
sumber
3
Saya pernah membaca posting terkait dari Robert Sheldon, tetapi tidak (IMHO) punya teori atau bukti yang menjelaskan perilaku contoh saya.
jyao
1
"Tidak ada dua nilai NULL yang sama." OK tapi bahkan orang-orang yang tahu itu akan berharap sebaliknya ketika ansi nulls dimatikan. Terutama karena WHERE NULL = NULLhasil yang benar ketika pengaturan.
ypercubeᵀᴹ
1

Untuk menambah diskusi, definisi standar NULL SQL92 dapat diartikan secara ambigu. Berikut ini adalah ringkasan yang baik dari penanganan dan interpretasi NULL dari berbagai DBMS yang berasal dari sqlite.org.

PENGUNGKAPAN : Saya agak ingat membaca tentang "ambiguitas" SQL92 dari versi yang lebih lama (seperti 6-8 tahun yang lalu) dari halaman sqlite.org yang ditautkan di atas, tetapi sejak saat itu halaman tersebut telah diperbarui.

Jawaban RLF di atas memiliki kutipan yang bagus, tetapi jika saya tidak setuju dengan Robert Sheldon, itu hanya karena saya menganggap "sesuatu yang tidak ada" (yaitu NULL ) sebagai filosofis dan bahasa Inggris-secara semantik setara dengan "sesuatu yang lain yang tidak ada ". Jika saya memahami logika Sheldon, maka orang dapat mendeklarasikan definisi NULL juga NULL. (Jika tidak ada, lalu bagaimana kita bisa mendefinisikannya? Menyeramkan, ya?)

Saya melihat variasi pembuatan bir Russell's Paradox ( dan sakit kepala). : - \

Tetapi sekali lagi, ini adalah diskusi tentang semantik bahasa Inggris ( BUKAN SQL) dan perdebatan filosofi menjadi milik di sini . :-)

pr1268
sumber
PS Saya baru di sini untuk komunitas SE ini; jika ini telah dibahas nauseum iklan sebelumnya, maka saya minta maaf.
pr1268
1
Di mana tepatnya ambiguitas dalam standar?
ypercubeᵀᴹ
@ ypercubeᵀᴹ: Saya percaya ambiguitas terletak pada upaya untuk "memasukkan" 3VL ke dalam Boolean. Tabel yang digabungkan dengan perbandingan NULL dapat diinterpretasikan dengan beberapa cara berbeda.
pr1268
Saya akan setuju tentang inkonsistensi tetapi bukan tentang ambiguitas.
ypercubeᵀᴹ
1
@ ypercubeᵀᴹ: Cukup adil ... Saya hanya mengutip apa yang versi lawas dari halaman sqlite.org yang saya tautkan di atas berkata ("SQL92 ambigu berkaitan dengan penanganan dan interpretasi NULL" atau sesuatu yang sangat mirip). Tapi saya tidak bermaksud berdebat. Mungkin halaman sqlite.org itu sendiri menyesatkan dan / atau benar-benar salah. Yang mungkin menjelaskan mengapa itu diperbarui.
pr1268