鑑於當CASE語句也意外的行爲:SQL服務器:比較NULL
下面的SELECT語句:
select case NULL
when NULL then 0
else 1
end
問題:
我期待這個返回0而是它返回1.什麼給了?
鑑於當CASE語句也意外的行爲:SQL服務器:比較NULL
下面的SELECT語句:
select case NULL
when NULL then 0
else 1
end
問題:
我期待這個返回0而是它返回1.什麼給了?
一般來說,NULL不是你應該試圖比較的相等性,這是case語句所做的。你可以使用「Is NULL」來測試它。沒有期望NULL != NULL
或NULL = NULL
。這是一個不確定的,未定義的值,而不是一個硬性常數。
- 涵蓋在評論的問題 -
如果您需要檢索時可能遇到的一個NULL列中的值,試試這個來代替:
Case
When SomeColumn IS NULL
Then 0
Else 1
End
我認爲,應該工作。就你原來的帖子而言:
Select Case NULL
When NULL then 0 // Checks for NULL = NULL
else 1 // NULL = NULL is not true (technically, undefined), else happens
end
問題在於你的Case選擇會自動嘗試使用相等操作。這根本不適用於NULL。
您需要使用IS NULL運算符。標準比較運算符不適用於NULL。
退房有關NULL這些MSDN文章,可能是有用的:
除了其他的答案,你需要稍微改變一下語法CASE
到這樣做:
SELECT CASE
WHEN NULL IS NULL THEN 0
ELSE 1
END;
在您的語法中使用該值隱式使用等於比較。 NULL
是未知的,所以是NULL = NULL
,所以用你現在的代碼,你將永遠得到
零
1(geez我也是)。
要獲得您想要的行爲,您可以使用SET ANSI_NULLS ON;但請注意,這可能會以您無法預測的方式更改其他代碼,並且該設置已棄用 - 因此它將在SQL Server的未來版本中完全停止工作(請參閱this SQL Server 2008 doc)。
我打算在Aaron的答案中加入這個評論,但是它太長了,所以我會把它作爲另一個答案的一部分加入。
CASE
statement實際上有兩種不同的模式,簡單和搜索。
從BOL:
的情況下表達有兩種格式:
簡單情況下表達的表達與一組簡單的表達式來確定結果。
CASE搜索表達式計算一組布爾表達式以確定結果。
當簡單CASE
(你的例子)做什麼它描述爲比較它的相等比較 - 即=
這就是後來的文件中明確:
簡單情況下表達被第一表達 比較操作在每個WHEN子句中用於等價的表達式。如果這些 表達式是等價的,則THEN子句中的表達式將返回 。
- 只允許相等性檢查。
因爲anything = NULL
是ANSI SQL總是假的(如果你不知道這沒有,你需要更多的一般在SQL的NULL讀了,尤其還與其他行爲的搜索比較 - WHERE x IN (a, b, c)
),你不能在簡單的情況下,無論是在最初的表達或表達的列表,針對被比較使用NULL
,並它曾經被比作一個值,具有NULL
。
如果你想檢查NULL
,你將不得不使用IF/ELSE
結構或搜索CASE
一個完整的表達式。
我同意,這是種不幸沒有版本支持的還是比較更容易寫:
select case colname
when IS NULL then 0
else 1
end
這將使編寫更容易某些長CASE
聲明:
select case colname
when IS NULL then ''
when 1 then 'a'
when 2 then 'b'
when 3 then 'c'
when 4 then 'd'
else 'z'
end
但這只是一廂情願的想法...
一個選項是使用ISNULL
或COALESCE
:
select case COALESCE(colname, 999999) -- 999999 is some value never used
when 999999 then ''
when 1 then 'a'
when 2 then 'b'
when 3 then 'c'
when 4 then 'd'
else 'z'
end
但它並不總是一個很好的選擇。
+1真棒帖子,凱德。 – DJTripleThreat
@Martin - 沒錯。你不應該使用NULL的比較運算符。 'IS NULL'是正確的方法。我的'NULL!= NULL'是試圖比較兩個可能包含NULL值的列的引用。即使它們都是NULL,它們也不相等。 –
@Martin - 對不起,當我重讀它時,我收集了你正在解釋的內容。你是對的,兩個比較運算符都不對NULL。我試着清理一下答案。 –
好的,那麼讓我問你:當我比較一個空值的列正在做同樣的事情時,我遇到了這個問題。那麼,爲什麼'選擇case SomeColumn當NULL然後0 else 1 end'或者你是說問題在於when子句而不是select case? – DJTripleThreat