奇怪的WHERE col = NULL行为

Ken*_*eth 3 sql-server null

这是我们的开发人员带给我的一个问题.他偶然发现了一个旧的存储过程,它多次使用'WHERE col = NULL'.执行存储过程时,它返回数据.

如果存储过程内的查询是手动执行的,除非'WHERE col = NULL'引用更改为'WHERE col IS NULL',否则它将不会返回数据.

谁能解释这种行为?

And*_*mar 5

这是设计的:如果你比较任何东西null,它评估为unknown.任何逻辑unknown本身unknown.所以任何陈述anything = null 都将是假的.

这两个结构之间的重要区别是:

1 = null --> unknown
1 is null --> false
Run Code Online (Sandbox Code Playgroud)

所以:

1 = null or 1=1 --> unknown (false)
1 is null or 1=1 --> true
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,unknown玷污整个表达.

根据评论,更好的答案可能是检查ANSI_NULL,其中:

SELECT SESSIONPROPERTY ('ANSI_NULLS')
Run Code Online (Sandbox Code Playgroud)

如果返回false,则= null构造将如下所示is null:

set ansi_nulls on -- default
SELECT SESSIONPROPERTY ('ANSI_NULLS') -- 1
select 1 where not null = 1 -- no rows returned
set ansi_nulls off
SELECT SESSIONPROPERTY ('ANSI_NULLS') -- 0
select 1 where not null = 1 -- returns a row
Run Code Online (Sandbox Code Playgroud)

但是默认是ansi_nulls on这样,看到它关闭是非常不寻常的.存储过程会记住创建时的设置:

set ansi_nulls off
go
create procedure dbo.TestNulls as select 1 where not null = 1
go
set ansi_nulls on
exec dbo.TestNulls -- Still prints a row
Run Code Online (Sandbox Code Playgroud)

您可以通过从SSMS编写过程脚本来检查已保存的设置.