5

以下

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

为什么会这样?

4

6 回答 6

7

IF这两种说法 都不正确。NULL既不等于某物,也不等于某物。IS NULL要么要么的东西IS NOT NULL

于 2013-05-16T21:13:01.070 回答
2

同意其他人已经说过的话。换个角度简单评论一下,如果你尝试设置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'
于 2013-05-16T22:38:03.680 回答
2

它既不等于也不不等于,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 请求该功能的链接:

http://connect.microsoft.com/SQLServer/feedback/details/286422/add-language-and-optimizer-support-for-iso-distinct-predicate

这是一个常见的要求,但是为许多列编码既乏味又容易出错(尤其是因为 AND/OR 优先级问题)。更改 ANSI_NULLS 的设置不是解决方案,因为它不会影响列到列的比较,只会影响列到变量的比较。将 ANSI_NULLS 设置为 off 也是非标准的,并且不够精细,无法应用于单个查询中的特定比较。

于 2013-05-16T21:32:49.523 回答
1

你不能比较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。

http://msdn.microsoft.com/en-us/library/aa933227

于 2013-05-16T21:13:59.207 回答
1

这很简单。在 ANSI 术语中,任何涉及 NULL 的表达式(逻辑或算术)都有未知结果:

(1 = NULL) IS UNKNOWN
(1 <> NULL) IS UNKNOWN
(1 + NULL) IS UNKNOWN
(1 * NULL) IS UNKNOWN

因此,在这两种情况下,您最终都会进入 ELSE 分支。

试试这个链接以获得更多解释。

于 2013-05-16T21:15:30.917 回答
0

我猜 NULL 指定它在某种程度上是 <,>,=,!= 运算符无法比较的。这种比较可能返回 NULL。然后if(NULL)跳过处理。

于 2013-05-16T21:13:25.387 回答