2010-06-04 60 views
4

這更多的是爲了滿足自己的好奇心。考慮下面的語句:SQL Server 2005 - 在比較中使用空值

DECLARE @result BIT 
SET @result = CASE WHEN NULL <> 4 THEN 0 
        ELSE 1 
       END 
PRINT @result 

爲什麼我回來 「1」,而不是 「0」

將其更改爲:

DECLARE @result BIT 
SET @result = CASE WHEN NULL IS NULL 
         OR NULL <> 4 THEN 0 
        ELSE 1 
       END 
PRINT @result 

正確給我回 「0」

我知道NULL比較可能會很棘手,但這個特殊的例子在我們的代碼審查過程中滑過。

任何澄清,將不勝感激

回答

9

這是因爲3 valued logic。在第一種情況不明不計算爲真讓你在別的

DECLARE @result BIT 
SET @result = CASE WHEN Unknown THEN 0 
        ELSE 1 
       END 
PRINT @result 

最終在第二種情況下,你在做真正的或未知的計算結果爲真。

DECLARE @result BIT 
SET @result = CASE WHEN True 
         OR Unknown THEN 0 
        ELSE 1 
       END 
PRINT @result 
+0

您的代碼不能在Management Studio中編譯。你確定這個有效的T-Sql(這是一個SQL 2005的具體問題)?我從來沒有見過T-sql中使用的UNKNOWN關鍵字。 – luksan 2010-06-04 17:37:35

+0

@luksan我在替換真值表中的值試圖有幫助它不是有效的SQL! – 2010-06-04 17:39:05

+2

它的僞代碼。 – JNappi 2010-06-04 17:40:10

1

這是由於ANSI SQL標準和比較運算符的行爲與NULL。無論何時您想要將值與可能爲NULL的值進行比較,都需要使用IS運算符來顯式檢查值可能爲NULL的情況。或者您可以禁用SQL Server中的ANSI_NULLS選項。

下面的例子做你想要什麼:

DECLARE @result BIT 
DECLARE @input INT 

SET @input = NULL 
SET @result = CASE WHEN (@input IS NULL OR @input <> 4) THEN 0 
        ELSE 1 
       END 
PRINT @result 

或者這樣:

SET ANSI_NULLS OFF 

DECLARE @result BIT 
SET @result = CASE WHEN NULL <> 4 THEN 0 
        ELSE 1 
       END 
PRINT @result 

參考文獻:

http://msdn.microsoft.com/en-us/library/ms188048.aspx

1

從純技術的角度來看,之所以第一個語句返回1是因爲ANSI_NULLS設置爲「ON」將NULL視爲符合ISO標準的「未知」。

要讓值按照您的預期進行評估,請在您的腳本前面運行SET ANSI_NULLS OFF

在現實生活中,當然,ISNULL()是最令人敬畏/最安全的方法。

+0

我同意使用isnull真棒,但我不會稱之爲「安全」。你必須知道你的基礎數據類型和長度,這會削減它的許多無憂無慮。即,當isnull(A.Field,'這是一個空值')= isnull(B.Field,'這是一個空值'),那麼如果A.Field是varchar(4),那麼1'將不返回1。和B.Field是varchar(10)。但是,如果您選擇一個最小的替代值,您可能不得不擔心它是否意外地匹配表中的實際值。 – Matt 2013-02-11 17:38:48