以下
IF 1 = NULL
BEGIN
SELECT 'A'
END
ELSE
BEGIN
SELECT 'B'
END
按预期返回结果 B
这就是事情变得非常有趣的地方
IF 1 != NULL
BEGIN
SELECT 'A'
END
ELSE
BEGIN
SELECT 'B'
END
也返回 B
为什么会这样?
IF
这两种说法 都不正确。NULL
既不等于某物,也不等于某物。IS NULL
要么要么的东西IS NOT NULL
。
同意其他人已经说过的话。换个角度简单评论一下,如果你尝试设置ansi_nulls
为 off,你可能会得到你所期望的:
set ansi_nulls off
if 1 = null
select 'a'
else
select 'b' -- Returned
if 1 != null
select 'a' -- Returned
else
select 'b'
来自在线图书的更多信息:
当 SET ANSI_NULLS 为 OFF 时,等于 (=) 和不等于 (<>) 比较运算符不遵循 ISO 标准。使用 WHERE column_name = NULL 的 SELECT 语句返回 column_name 中具有空值的行。使用 WHERE column_name <> NULL 的 SELECT 语句返回列中具有非空值的行。此外,使用 WHERE column_name <> XYZ_value 的 SELECT 语句会返回所有非 XYZ_value 且非 NULL 的行。
这就ansi_nulls off
解释了。但是,不要试图简单地将其关闭,因为:
在 SQL Server 的未来版本中,ANSI_NULLS 将始终为 ON,任何显式将该选项设置为 OFF 的应用程序都将生成错误。避免在新的开发工作中使用此功能,并计划修改当前使用此功能的应用程序。
请遵循以下建议:
要使脚本按预期工作,无论 ANSI_NULLS 数据库选项或 SET ANSI_NULLS 的设置如何,请在可能包含空值的比较中使用 IS NULL 和 IS NOT NULL。
if 1 is null
select 'a'
else
select 'b' -- Returned
if 1 is not null
select 'a' -- Returned
else
select 'b'
它既不等于也不不等于,NULL
因为NULL
它不是一个事物,而是事实上,一个事物的不存在。
ANSI SQL 1999(虽然还不是 MSSQL)包括一个被调用的方法IS [NOT] DISTINCT FROM
,它可以用于NULL
您可能期望的结果。
如何重写 IS DISTINCT FROM 和 IS NOT DISTINCT FROM?
这是Itzik Ben-Gan的一篇关于IS DISTINCT FROM
行为和一般混淆性质的优秀文章NULL
http://sqlmag.com/sql-server/not-distinct
谓词可以评估为 TRUE、FALSE 或 UNKNOWN。每当涉及 NULL 时,谓词的计算结果为 UNKNOWN。
这是 Erland Sommarskog 的愿望:
http://www.sommarskog.se/wishlist.html#isdistinctfrom
SQL:1999 定义了运算符 IS DISTINCT FROM 和 IS NOT DISTINCT FROM,它们分别与 <> 和 = 相同,但它们也适用于 NULL 值。
(来自 Erland)这里是 Connect for MVP Steve Kass 请求该功能的链接:
这是一个常见的要求,但是为许多列编码既乏味又容易出错(尤其是因为 AND/OR 优先级问题)。更改 ANSI_NULLS 的设置不是解决方案,因为它不会影响列到列的比较,只会影响列到变量的比较。将 ANSI_NULLS 设置为 off 也是非标准的,并且不够精细,无法应用于单个查询中的特定比较。
你不能比较NULL
= NULL
- 它没有价值。
SELECT 1
WHERE NULL = NULL
不返回任何东西
比较NULL
值时IS
不使用=
SELECT 1
WHERE NULL IS NULL
返回 1
来自 MSDN:
要确定表达式是否为 NULL,请使用 IS NULL 或 IS NOT NULL 而不是比较运算符(例如 = 或 !=)。如果一个或两个参数为 NULL,则比较运算符返回 UNKNOWN。
这很简单。在 ANSI 术语中,任何涉及 NULL 的表达式(逻辑或算术)都有未知结果:
(1 = NULL) IS UNKNOWN
(1 <> NULL) IS UNKNOWN
(1 + NULL) IS UNKNOWN
(1 * NULL) IS UNKNOWN
因此,在这两种情况下,您最终都会进入 ELSE 分支。
试试这个链接以获得更多解释。
我猜 NULL 指定它在某种程度上是 <,>,=,!= 运算符无法比较的。这种比较可能返回 NULL。然后if(NULL)
跳过处理。