鉴于:
以下Select语句:
select case NULL
when NULL then 0
else 1
end
问题:
我希望这会返回0但是它返回1.什么给出了?
答案 0 :(得分:9)
一般来说,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 select会自动尝试使用相等操作。这根本不适用于NULL。
答案 1 :(得分:4)
我打算将此添加为对Aaron答案的评论,但是它太长了,所以我将其添加为另一部分(答案的一部分)。
CASE
statement实际上有两种不同的模式,简单和搜索。
来自BOL:
CASE表达式有两种格式:
简单的CASE表达式将表达式与一组简单表达式进行比较,以确定结果。
搜索到的CASE表达式计算一组布尔表达式以确定结果。
当简单的CASE
(您的示例)执行其描述为比较时,它执行相等比较 - 即=
这在后面的文档中阐明:
简单的CASE表达式通过比较第一个表达式来运行 到每个WHEN子句中的表达式的等价性。如果这些 表达式是等价的,THEN子句中的表达式将是 返回。
- 仅允许进行相等检查。
因为{1}在ANSI SQL中始终为false(如果您不知道这一点,则需要更一般地读取SQL中的NULL,尤其是其他搜索比较中的行为 - {{ 1}}),你不能在一个简单的情况下使用anything = NULL
并将它与一个值进行比较,在初始表达式或列表中有一个WHERE x IN (a, b, c)
要与之比较的表达方式。
如果您要查看NULL
,则必须使用NULL
构造或带有完整表达式的搜索NULL
。
我同意很遗憾没有支持IS比较的版本,以便更容易编写:
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
但它并不总是一个很好的选择。
答案 2 :(得分:3)
除了其他答案之外,您还需要稍微更改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)。
答案 3 :(得分:0)
您需要使用IS NULL运算符。标准比较运算符不适用于NULL。
答案 4 :(得分:0)
查看这些可能有用的关于Null的MSDN文章: