运算符 NOT 不会反转 NULL 比较的结果

operator NOT does not invert the result of a NULL comparison

请看这两条语句:

select 'true'  where (1 = NULL) ; 

select 'true' where not (1 = NULL) ;

两个 (!) return 都是空的!

所以这意味着表达式 (1=NULL)not (1=NULL) 都是 return 错误!但这怎么可能呢?我以为运算符 NOT(expression) 会反转表达式的结果 ?

根据微软:"Comparing NULL to a non-NULL value always results in FALSE."

好的,但这意味着运算符 NOT 必须反转结果。但是为什么它不这样做呢?

https://msdn.microsoft.com/en-us/library/ms188074.aspx

编辑:我发布了错误的文章。 我上面的引用来自这篇文章:https://msdn.microsoft.com/en-us/library/ms175118.aspx

这篇文章似乎有错误,如下答案和评论中所述。

我认为您在文档中发现了一个错误,但它不在您 link 访问的页面上,而是在另一页上。

问题中的 link 指出:

When SET ANSI_NULLS is ON, an operator that has one or two NULL expressions returns UNKNOWN. When SET ANSI_NULLS is OFF, the same rules apply, except an equals (=) operator returns TRUE if both expressions are NULL. For example, NULL = NULL returns TRUE when SET ANSI_NULLS is OFF.

因此,无论您在 SET ANSI_NULLS 中使用什么值,语句 1 = null 都会产生 UNKNOWN 值。

然而,在 = (Equals) (Transact-SQL) page, 备注部分指出:

Comparing NULL to a non-NULL value always results in FALSE.

显然不是这样,因为 1 = null 不是 return FALSE,而是 return UNKNOWN

因此,我的结论是 = 运算符文档中的错误。

参见:SET ANSI_NULLS (Transact-SQL)

Specifies ISO compliant behavior of the Equals (=) and Not Equal To (<>) comparison operators when they are used with null values in SQL Server 2016.

In a future version of SQL Server, ANSI_NULLS will always be ON and any applications that explicitly set the option to OFF will generate an error. Avoid using this feature in new development work, and plan to modify applications that currently use this feature.

因此,如果您使用它并将其设置为 OFF,您的代码将按预期运行:

SET ANSI_NULLS OFF

select 'true'  where (1 = NULL) ; 

select 'true' where not (1 = NULL) ;

但是按照文档中的说明,以后会出错

因此,T-SQL 实现了所谓的 Three-Valued Logic. That means that each logical expression present in T-SQL code can evaluate to TRUE, FALSE OR NULL. Now SQL Server gives you 2 options to handle logical expressions with NULLs with the SET ANSI_NULL 命令。 SQL 服务器 (SET ANSI_NULL ON) 的默认行为是每次与 NULL 的逻辑比较都会 return NULL。所以下面的表达式

NULL = NULL;
1 = NULL;
1 <> NULL;

将全部评估为 NULL。如果出于某种原因你希望逻辑表达式为 return true 或 false,即使它们中有 NULL 值,你也必须关闭 ANSI_NULL 但这是不可取的。

小编辑:包含 NULL 的逻辑表达式计算结果不是 NULL 的唯一情况如下:

(NULL) OR (TRUE) = TRUE

所以下面T-SQL代码

SET ANSI_NULLS ON;
GO
IF ((NULL=NULL) OR (1=1))
   PRINT 'True';
GO

实际上会打印 True.

使用 NULL

检查或比较值的更好方法
select 'true'  where 1 IS NULL ; 

select 'true' where 1 IS NOT NULL ;