定义是:

When SET ANSI_NULLS is ON, a SELECT statement that uses WHERE column_name = NULL returns zero rows even if there are null values in column_name. A SELECT statement that uses WHERE column_name <> NULL returns zero rows even if there are non-null values in column_name.

这是否意味着此查询中不包含空值?

SELECT Region
FROM employees
WHERE Region = @region

或者ANSI_NULL只涉及像这样的查询(其中WHERE包含特定的单词NULL)?

SELECT Region
FROM employees
WHERE Region = NULL

推荐答案

这意味着在第一个示例中使用@region时,如果@regionNULL,则不会返回任何行,即使表中有RegionNULL的行.

ANSI_NULLS为开时(无论如何,您都应该将其设置为开,因为不启用它的选项将在将来被删除),任何(至少)一个操作数为NULL的比较操作都会产生第三个逻辑值-UNKNOWN(与TRUEFALSE相反).

如果UNKNOWN个值尚未确定(例如ANDFALSE个操作数或ORTRUE个操作数)或求反(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,结果为NULL1,遵循ANSI惯例,即NULL(或未知)值不等于另一个NULL或未知值.

如果将ANSI_NULLS设置为OFF,则NULLNULL的比较结果为TRUE.

NULL与非NULL值进行比较总是得到FALSE2.

然而,12都是不正确的——两个比较的结果都是UNKNOWN.


*多年后,这段文字的神秘含义终于被发现.这实际上意味着,对于这些比较来说,设置没有任何影响.如果它说SET ANSI_NULLS OFF是没有效果的设置,就会更清楚.

Sql相关问答推荐

postgresql插入json不工作

如何在SQL Server中列出从当前月份开始的过go 10年中的月份

用于匹配红旗和绿旗的SQL查询

将重复的值更新为下一个空闲数字

连接三个表的正确方式是什么?在这三个表中,可以显示在一个表上的行将在其他表中显示结果

按日期时间(不包括秒)连接表

关于Postgres横向联接的谓词

将两列相加为同一表中的行的查询

使用拆分器将已分组的不同值连接在一起

PATINDEX中与[A-Z]匹配(U除外)的正则表达式

在 PostgreSQL 中生成时间序列查询

从选定记录中提取摘要作为值的划分

在特定条件下使用 LAG,确定要采用什么 LAG 值?

SQL Server - 复杂场景 - 比较状态并填充值到后续行

Postgres存在限制问题「小值」

按所选的值将记录分组到不同的列中

使用标准SQL 触发更新当前日期

有条件求和

Oracle REGEXP_REPLACE 开头的数字和空格

try 将 json 转换为字符串 (Athena AWS)