这意味着在第一个示例中使用@region
时,如果@region
是NULL
,则不会返回任何行,即使表中有Region
是NULL
的行.
当ANSI_NULLS
为开时(无论如何,您都应该将其设置为开,因为不启用它的选项将在将来被删除),任何(至少)一个操作数为NULL
的比较操作都会产生第三个逻辑值-UNKNOWN
(与TRUE
和FALSE
相反).
如果UNKNOWN
个值尚未确定(例如AND
与FALSE
个操作数或OR
与TRUE
个操作数)或求反(NOT
),则它们将通过任何组合布尔运算符传播.
WHERE
子句用于过滤FROM
子句生成的结果集,因此WHERE
子句的总值必须为TRUE
,才能不过滤掉该行.因此,如果通过任何比较生成UNKNOWN
,它将导致该行被过滤掉.
@user1227804的answer包括以下报价:
如果比较的两侧都是列或复合表达式,则该设置不会影响比较.
从SET ANSI_NULLS
开始*
然而,我不确定它想表达什么观点,因为如果比较两个NULL
列(例如在JOIN
中),比较仍然失败:
create table #T1 (
ID int not null,
Val1 varchar(10) null
)
insert into #T1(ID,Val1) select 1,null
create table #T2 (
ID int not null,
Val1 varchar(10) null
)
insert into #T2(ID,Val1) select 1,null
select * from #T1 t1 inner join #T2 t2 on t1.ID = t2.ID and t1.Val1 = t2.Val1
上述查询返回0行,而:
SELECT * FROM #T1 t1 INNER JOIN #T2 t2
ON t1.ID = t2.ID
AND ( t1.Val1 = t2.Val1
OR t1.Val1 IS NULL
AND t2.Val1 IS NULL )
返回一行.因此,即使两个操作数都是列,NULL
也不等于NULL
.documentation for =
对操作数没有什么可说的:
比较两个NULL
表达式时,结果取决于ANSI_NULLS
设置:
如果将ANSI_NULLS
设置为ON
,结果为NULL
1,遵循ANSI惯例,即NULL
(或未知)值不等于另一个NULL
或未知值.
如果将ANSI_NULLS
设置为OFF
,则NULL
与NULL
的比较结果为TRUE
.
将NULL
与非NULL
值进行比较总是得到FALSE
2.
然而,1和2都是不正确的——两个比较的结果都是UNKNOWN
.
*多年后,这段文字的神秘含义终于被发现.这实际上意味着,对于这些比较来说,设置没有任何影响.如果它说SET ANSI_NULLS OFF
是没有效果的设置,就会更清楚.