鉴于当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