奇怪的WHERE col = NULL行为

时间:2010-04-08 20:21:59

标签: sql-server null

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

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

任何人都可以解释这种行为吗?

3 个答案:

答案 0 :(得分:5)

这是设计的:如果您将任何内容与null进行比较,则评估为unknownunknown的任何逻辑本身都是unknown。所以anything = null的任何陈述都将是假的。

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

1 = null --> unknown
1 is null --> false

所以:

1 = null or 1=1 --> unknown (false)
1 is null or 1=1 --> true

你可以看到,unknown玷污了整个表达。

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

SELECT SESSIONPROPERTY ('ANSI_NULLS')

如果这返回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

默认值为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

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

答案 1 :(得分:3)

好的,我想我应该回答:

检查ANSI_NULLS设置

答案 2 :(得分:0)

在SQL中,X = NULL将始终评估为false,因为NULL表示缺少数据,无法判断它是否等于“另一个”缺少数据(NULL = NULL为false) 。这就是IS关键字存在的原因......