2013-05-16 30 views
5

Sau đâyTại sao kết quả cho 1 = NULL và 1! = NULL giống nhau?

IF 1 = NULL 
    BEGIN 
     SELECT 'A' 
    END 
ELSE 
    BEGIN 
     SELECT 'B' 
    END 

Trả về kết quả như mong đợi B

Đây là nơi mọi thứ trở nên thực sự thú vị

IF 1 != NULL 
    BEGIN 
     SELECT 'A' 
    END 
ELSE 
    BEGIN 
     SELECT 'B' 
    END 

Cũng trả B

Tại sao đây là trường hợp?

+3

Bạn không thể bằng 'không có gì'. – sircodesalot

+1

'NULL' không bao giờ bằng, không bằng, lớn hơn hoặc ít hơn bất cứ thứ gì. –

+0

Thật sao? Nó không thể không bằng nhau? –

Trả lời

2

Đồng ý với những gì mọi người khác đã nói. Đơn giản chỉ cần cho ý kiến ​​từ một góc độ khác, nếu bạn cố gắng thiết lập ansi_nulls để tắt, bạn có thể có được những gì bạn mong đợi:

set ansi_nulls off 

if 1 = null 
    select 'a' 
else 
    select 'b' -- Returned 


if 1 != null 
    select 'a' -- Returned 
else 
    select 'b' 

Thông tin thêm từ sách trực tuyến:

Khi SET ANSI_NULLS là OFF, Equals (=) và không bằng (<>) toán tử so sánh không tuân theo tiêu chuẩn ISO. Câu lệnh SELECT sử dụng WHERE column_name = NULL trả về các hàng mà có giá trị null trong cột_name. Câu lệnh SELECT sử dụng WHERE column_name <> NULL trả về các hàng có giá trị không trống trong cột . Ngoài ra, một câu lệnh SELECT sử dụng WHERE column_name <> XYZ_value trả về tất cả các hàng không phải là XYZ_value và không phải là NULL.

Đó là ansi_nulls off giải thích. Tuy nhiên, không bị cám dỗ chỉ đơn giản là tắt vì:

Trong một phiên bản tương lai của SQL Server, ANSI_NULLS sẽ luôn là ON và bất kỳ ứng dụng mà thiết lập một cách rõ ràng tùy chọn để OFF sẽ tạo lỗi. Tránh sử dụng tính năng này trong công việc phát triển mới và lập kế hoạch để sửa đổi các ứng dụng hiện đang sử dụng tính năng này.

Thực hiện theo các khuyến nghị dưới đây thay vì:

Đối với một kịch bản để làm việc như dự định, không phụ thuộc vào tùy chọn cơ sở dữ liệu ANSI_NULLS hoặc các thiết lập của SET ANSI_NULLS, sử dụng IS NULL và IS NOT NULL trong so sánh có thể chứa giá trị null.

if 1 is null 
    select 'a' 
else 
    select 'b' -- Returned 


if 1 is not null 
    select 'a' -- Returned 
else 
    select 'b' 
7

Không có tuyên bố IF nào là đúng. NULL không bằng một cái gì đó cũng không bằng một cái gì đó. Một cái gì đó hoặc là IS NULL hoặc IS NOT NULL.

0

Tôi đoán NULL được xác định rằng theo một cách nào đó, không thể so sánh được với các toán tử <,>, =,! =. So sánh như vậy có thể trả về NULL. Sau đó, việc xử lý if(NULL) bị bỏ qua.

1

Bạn không thể so sánh NULL = NULL - không có giá trị.

SELECT 1 
WHERE NULL = NULL 

Không trả về bất cứ điều gì

Khi so sánh NULL giá trị sử dụng IS không =

SELECT 1 
WHERE NULL IS NULL 

Reuturns 1

Từ MSDN:

Để xác định biểu thức là NULL, sử dụng IS NULL hoặc IS NOT NULL thay vì toán tử so sánh (chẳng hạn như = hoặc! =). So sánh các toán tử trả về UNKNOWN nếu một trong hai hoặc cả hai đối số là NULL.

http://msdn.microsoft.com/en-us/library/aa933227

1

Nó đơn giản. Về ANSI, bất kỳ biểu thức (logic hoặc số học) liên quan đến NULL có kết quả chưa biết:

(1 = NULL) IS UNKNOWN 
(1 <> NULL) IS UNKNOWN 
(1 + NULL) IS UNKNOWN 
(1 * NULL) IS UNKNOWN 

Vì vậy, trong cả hai trường hợp, bạn kết thúc trong các chi nhánh ELSE.

Thử liên kết this để được giải thích thêm.

+1

Từ liên kết của bạn _... tất cả so sánh với giá trị null được đánh giá là UNKNOWN_ sẽ chỉnh sửa câu trả lời của bạn cho đúng. –

+0

@ShannonSeverance Nghe có vẻ tốt hơn. Bạn không thể truy vấn SELECT 1 = NULL - điều này không phân tích cú pháp. Tôi sẽ nhớ bình luận của bạn. –

+0

Từ vựng bị nhầm lẫn. PL/SQL có kiểu dữ liệu Boolean. Booleans có thể lấy ba giá trị: 'true',' false' và 'null'. –

2

Nó không bằng hoặc không bằng NULLNULL không phải là điều nhưng, trên thực tế, sự vắng mặt của một vật.

ANSI SQL 1999 (không phải MSSQL), bao gồm một phương pháp được gọi là IS [NOT] DISTINCT FROM có thể được sử dụng trên NULL với kết quả bạn có thể mong đợi.

How to rewrite IS DISTINCT FROM and IS NOT DISTINCT FROM?

Dưới đây là một bài tuyệt vời trên IS DISTINCT FROM hành vi và bản chất khó hiểu của NULL nói chung bởi Itzik Ben-Gan

http://sqlmag.com/sql-server/not-distinct

Các vị có thể đánh giá là TRUE, FALSE hoặc KHÔNG XÁC ĐỊNH. Các vị ngữ đánh giá để UNKNOWN bất cứ khi nào NULL có liên quan.

Dưới đây là Erland Sommarskog có nhu cầu cho nó:

http://www.sommarskog.se/wishlist.html#isdistinctfrom

SQL: 1999 định nghĩa các nhà khai thác khác với và IS NOT DISTINCT TỪ mà cũng giống như <> và = tương ứng, ngoại trừ việc chúng cũng áp dụng cho các giá trị NULL.

(Từ Erland) đây là một liên kết trên Connect cho MVP Steve Kass yêu cầu tính năng:

http://connect.microsoft.com/SQLServer/feedback/details/286422/add-language-and-optimizer-support-for-iso-distinct-predicate

Đây là một yêu cầu phổ biến, nhưng mã hóa này trong nhiều cột vừa là tẻ nhạt và dễ xảy ra lỗi (đặc biệt là do các vấn đề ưu tiên VÀ/HOẶC). Thay đổi thiết lập của ANSI_NULLS không phải là một giải pháp, bởi vì nó không ảnh hưởng đến so sánh cột-to-cột, chỉ có cột so sánh biến. Việc đặt ANSI_NULLS thành tắt cũng không chuẩn và không đủ chi tiết để áp dụng cho các so sánh cụ thể trong một truy vấn.

Các vấn đề liên quan