奇怪的 WHERE col = NULL 行为

发布于 2024-08-28 08:22:35 字数 198 浏览 5 评论 0原文

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

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

谁能解释这种行为?

This is a problem one of our developers brought to me. He stumbled across an old stored procedure which used 'WHERE col = NULL' several times. When the stored procedure is executed it returns data.

If the query inside the stored procedure is executed manually it will not return data unless the 'WHERE col = NULL' references are changed to 'WHERE col IS NULL'.

Can anyone explain this behavior?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

你げ笑在眉眼 2024-09-04 08:22:35

这是设计使然:如果您将任何内容与 null 进行比较,则其计算结果为 unknown。任何未知的逻辑本身就是未知。因此任何带有 anything = null 的语句都将始终为 false。

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

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 一样工作code>:

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 编写过程脚本来检查保存的设置。

That's by design: if you compare anything to null, it evaluates to unknown. Any logic with unknown is itself unknown. So any statement with anything = null will always be false.

The important difference is between these two constructs:

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

So:

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

So as you can see, unknown taints an entire expression.

Based on the comments, a better answer would probably be checking for ANSI_NULLs, with:

SELECT SESSIONPROPERTY ('ANSI_NULLS')

If this returns false, the = null construct would work like 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

The default is ansi_nulls on though, and it's very unusual to see it turned off. A stored procedure does remember the setting from the time it was created:

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

You can check the saved settings by scripting the procedure from SSMS.

盛装女皇 2024-09-04 08:22:35

好吧,我想我应该回答这个问题:

检查 ANSI_NULLS 设置

OK, guess I should have made this an answer:

Check the ANSI_NULLS setting

鲜血染红嫁衣 2024-09-04 08:22:35

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

In SQL, X = NULL will always evaluate to false, since NULL represents the absence of data, one cannot tell whether it is equal to "another" absence of data or not (NULL = NULL is false). This is why the IS keyword exists...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文