为什么SET ANSI_NULLS OFF无法比较字段?

时间:2012-02-10 19:24:37

标签: sql sql-server database null sql-server-2008-r2

我会认为SET ANSI_NULLS OFF模式非常方便,并且如果它一致地工作,它将默认使用它 - 允许使用=或!=到处比较空值。但它只有在我与显式内联null进行比较时才有效,但如果我与包含null的字段进行比较 - 它就不起作用了。为什么微软会这样设计呢? 难怪为什么没有人默认使用SET ANSI_NULLS OFF模式。我宁愿忍受“is null”和“is not null”的痛苦而不是考虑我使用内联和什么不是。

以下是显示问题的示例 - 与???一致应该返回2行,但它只返回一行。

CREATE TABLE t1 (a int null, b int null)
INSERT INTO t1 values (null,null)
INSERT INTO t1 values (0,null)
INSERT INTO t1 values (null,0)
INSERT INTO t1 values (0,0)
set ansi_nulls ON
select * from t1 where a=null -- empty result
select * from t1 where a=b  -- (0,0)
select * from t1 where null=null -- empty result
set ansi_nulls OFF
select * from t1 where a=null -- (null,null),(null,0)
select * from t1 where a=b -- why only (0,0) ???, it should be (0,0),(null,null)
select * from t1 where null=null -- returns all 4 rows
drop table t1

1 个答案:

答案 0 :(得分:6)

这是在这里回答的:

How does ANSI_NULLS work in TSQL?

设置ansi_nulls off仅影响比较,如果其中一个操作数是空变量或文字空值。

此外,您不应使用off设置编写任何新代码,因为将来不支持它:

http://msdn.microsoft.com/en-us/library/ms188048.aspx

更新

重新阅读你的问题之后,我认为你实际上是在解释为什么不这样做:

select * from t1 where a=b

这样的功能:

select * from t1 where a=b or (a=null and b=null)

将在您的示例中返回(null,null),(0,0)。

所以,你正在检查两个条件:

  1. 两个列值相等
  2. 两个列值都未知
  3. 当你的表达式写成a = null时,你很清楚你要做什么。但是如果写成a = b,你打算只检查第一个条件,还是两者都检查?

    另一种思考方式,比如你正在编写一个查询来返回所有拥有相同家庭+手机号码的客户。您是否希望返回这两列中具有空值的客户?

    简而言之,MSFT不希望在只有一个条件时自动检查两个条件 - 我认为这是正确的设计。