ANSI_NULLS如何在SQL中工作?

时间:2010-05-19 15:02:45

标签: tsql sql-server-2008 null

SET ANSI_NULLS OFF似乎在TSQL中给出不同的结果,具体取决于您是在比较表中的字段还是值。任何人都可以帮助我理解为什么我的最后两个查询没有结果?我不是在寻找解决方案,只是解释。

select 1 as 'Col' into #a
select NULL as 'Col' into #b

--This query gives results, as expected.  
SET ANSI_NULLS OFF
select * from #b
where NULL = Col

--This query gives results, as expected.
SET ANSI_NULLS OFF
select * from #a
where NULL != Col

--This workaround gives results, too.
select * from #a a, #b b
where isnull(a.Col, '') != isnull(b.Col, '')

--This query gives no results, why?
SET ANSI_NULLS OFF
select * from #a a, #b b
where a.Col != b.Col

--This query gives no results, why?
SET ANSI_NULLS OFF
select * from #a a, #b b
where b.Col != a.Col

2 个答案:

答案 0 :(得分:10)

最后两个查询失败的原因是SET ANSI_NULLS ON/OFF仅在您与变量或NULL值进行比较时适用。在比较列值时不适用。来自BOL:

  

SET ANSI_NULLS ON会影响比较   只有当其中一个操作数   比较是一个变量   是NULL或文字NULL。如果两者   比较的两边是列或   复合表达式,设置确实如此   不影响比较。

答案 1 :(得分:0)

与空值比较的任何内容都会失败。即使比较两个空值也会失败。即使是!=也会因为(恕我直言)愚蠢的NULL处理而失败。

那就是说,可以重写!=查询来说:

select * from #a a where a.Col not in (select b.Col from #b b)

最后一个查询与倒数第二个查询相同,因为比较顺序无关紧要。

顺便提一下,您的解决方法之所以有用,只是因为您正在测试#b.Col列中的空值并将其显式转换为'',然后允许您的查询在它们之间进行字符串比较。另一种写作方式是:

select * from #a a, #b b
where a.Col != COALESCE(b.Col, '')