Giá trị tự so sánh NULL trong một bảng


13

Tôi luôn bối rối về một số hành vi t-sql bí ẩn, như sau

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

Đây không phải là về cách lấy tất cả các hàng trong một bảng và cũng không phải là về việc tránh sử dụng ANSI_NULLS.

Tôi chỉ muốn thu hút một số hiểu biết tại sao t-sql hành xử như thế này.

Câu trả lời:


13

Đây là một hành vi đáng ngạc nhiên nhưng từ trang MSDN, SET ANSI_NULLSít nhất chúng ta có thể biết đó là hành vi dự kiến. Thêm một lý do để không bao giờ sử dụng ANSI_NULLS OFF:

SET ANSI_NULLSchỉ ảnh hưởng đến một phép so sánh nếu một trong các toán hạng của phép so sánh là một biến NULLhoặc theo nghĩa đen NULL. Nếu cả hai mặt của phép so sánh là cột hoặc biểu thức ghép, cài đặt không ảnh hưởng đến phép so sánh.


8

Mặc dù nó có thể không rõ ràng từ tài liệu msDN, tôi tin rằng bạn sẽ tìm thấy sự thật sau đây

"SET ANSI_NULLS ON chỉ ảnh hưởng đến một phép so sánh nếu một trong các toán hạng so sánh là một biến là NULL hoặc NULL theo nghĩa đen. Nếu cả hai mặt của phép so sánh là cột hoặc biểu thức ghép, cài đặt không ảnh hưởng đến phép so sánh."

Xem /programming/2866714/how-does-ansi-nulls-work-in-tsql


Cảm ơn Scott và ypercube, cả hai câu trả lời của bạn đều hướng đến điểm cho hành vi này, vì vậy tôi nêu lên cả hai câu trả lời của bạn.
jyao

Ypercube là lần đầu tiên :)
Scott Hodgin

4

Robert Sheldon trong bài viết sau từ năm 2015 thảo luận về các hành vi của NULL và tại sao đôi khi (nhưng không phải lúc nào) cũng thất bại

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

Ông mô tả 13 thất bại NULL mà một lập trình viên có thể dễ dàng vấp phải.

Thất bại # 1: Không biết NULL nghĩa là gì

Giải thích: NULL là một giá trị không tồn tại, không tồn tại. Nó không phải là không. Nó không phải là một chuỗi rỗng. Một giá trị không thể bằng NULL. Không có hai giá trị NULL bằng nhau .

Đó là vấn đề cơ bản, nhưng hãy chắc chắn đọc về những thất bại khác.

Có, các phiên bản trước đó (Tôi tin rằng SQL Server 7) hoạt động khác đi, giống như những gì bạn muốn.

Tuy nhiên, nếu bạn tìm kiếm vấn đề trên Stack Overflow và Stack Exchange, bạn sẽ tìm thấy nhiều luồng dài thảo luận về các vấn đề.


3
Tôi đã từng đọc bài đăng được liên kết từ Robert Sheldon, nhưng nó không (IMHO) không có bất kỳ lý thuyết hoặc bằng chứng nào giải thích hành vi của ví dụ của tôi.
jyao

1
"Không có hai giá trị NULL bằng nhau." OK nhưng ngay cả những người biết điều đó sẽ mong đợi điều ngược lại khi ansi nulls được tắt. Đặc biệt bởi vì WHERE NULL = NULLsản lượng đúng khi cài đặt là.
ypercubeᵀᴹ

1

Để thêm vào cuộc thảo luận, định nghĩa về NULL của tiêu chuẩn SQL92 có thể được diễn giải một cách mơ hồ. Đây là một bản tóm tắt tốt về xử lý và giải thích NULL từ các DBMS khác nhau của sqlite.org.

TIẾT LỘ : Tôi nhớ là đã đọc về "sự mơ hồ" của SQL92 từ một phiên bản cũ hơn (như 6-8 năm trước) của trang sqlite.org được liên kết ở trên, nhưng trang đó đã được cập nhật kể từ đó.

Câu trả lời của RLF ở trên có một câu trích dẫn hay, nhưng nếu tôi không đồng ý với Robert Sheldon thì đó chỉ là vì tôi coi "thứ gì đó không tồn tại" (tức là một NULL ) là tương đương về mặt triết học và ngôn ngữ tiếng Anh với "một thứ khác không tồn tại ". Nếu tôi hiểu logic của Sheldon, thì người ta có thể tuyên bố định nghĩa về NULL cũng là NULL. (Nếu nó không tồn tại, thì làm sao chúng ta có thể định nghĩa nó? Creepy, huh?)

Tôi thấy một biến thể của sản xuất bia Paradox của Russell ( đau đầu). : - \

Nhưng một lần nữa, đây là một cuộc thảo luận về ngữ nghĩa tiếng Anh ( KHÔNG phải SQL) và cuộc tranh luận về triết học thuộc về đây . :-)


PS Tôi mới ở đây với cộng đồng SE này; Nếu điều này đã được thảo luận về quảng cáo trước đó, thì tôi xin lỗi.
pr1268

1
Chính xác thì sự mơ hồ trong tiêu chuẩn ở đâu?
ypercubeᵀᴹ 27/8/2016

@ ypercubeᵀᴹ: Tôi tin rằng sự mơ hồ nằm trong nỗ lực "lắp" 3VL vào Boolean. Bảng tham gia với so sánh NULL có thể được diễn giải theo nhiều cách khác nhau.
pr1268

Tôi đồng ý về sự không nhất quán nhưng không phải về sự mơ hồ.
ypercubeᵀᴹ

1
@ ypercubeᵀᴹ: Đủ công bằng ... Tôi chỉ trích dẫn những gì một phiên bản cũ hơn của trang sqlite.org mà tôi đã liên kết ở trên đã nói ("SQL92 mơ hồ liên quan đến việc xử lý và giải thích NULL" hoặc một cái gì đó rất giống nhau). Nhưng tôi không có ý tranh luận. Có lẽ trang sqlite.org tự nó đã gây hiểu nhầm và / hoặc hoàn toàn không chính xác. Mà có khả năng giải thích tại sao nó được cập nhật.
pr1268
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.