这是我们的开发人员带给我的一个问题。他偶然发现了一个旧的存储过程,它多次使用'WHERE col = NULL'。 执行存储过程时,它会返回数据。
如果手动执行存储过程内的查询,除非'WHERE col = NULL'引用更改为'WHERE col IS NULL',否则它不会返回数据。
任何人都可以解释这种行为吗?
答案 0 :(得分:5)
这是设计的:如果您将任何内容与null
进行比较,则评估为unknown
。 unknown
的任何逻辑本身都是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
关键字存在的原因......