在SQL Server中,“SET ANSI_NULLS ON”是什么意思?

时间:2012-03-19 08:00:23

标签: sql tsql stored-procedures

定义说:

  

当SET ANSI_NULLS为ON时,即使column_name中存在空值,使用WHERE column_name = NULL的SELECT语句也会返回零行。使用WHERE column_name<>的SELECT语句即使column_name中存在非空值,NULL也会返回零行。

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

SELECT Region
FROM employees
WHERE Region = @region

ANSI_NULL仅关注此类查询(WHERE包含特定字词NULL)?

SELECT Region
FROM employees
WHERE Region = NULL

7 个答案:

答案 0 :(得分:54)

这意味着,如果@regionNULL,则在第一个示例中使用时不会返回任何行,即使表中的行RegionNULL也是如此}。

ANSI_NULLS打开时(无论如何都要设置它,因为将来不会删除没有打开的选项),任何比较操作,其中(至少)其中一个操作数NULL生成第三个逻辑值 - UNKNOWN(与TRUEFALSE相对)。

UNKNOWN值通过任何组合布尔运算符传播(如果它们尚未确定)(例如AND带有FALSE操作数或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,则结果为NULL 1 ,遵循ANSI约定NULL(或未知)值不等于另一个NULL或未知值。

     

如果ANSI_NULLS设置为OFF,则NULLNULL相比的结果为TRUE

     

NULL与非NULL值进行比较,总会产生FALSE 2

然而, 1 2 都不正确 - 两次比较的结果都是UNKNOWN


* 多年后终于发现了本文的神秘含义。实际意味着,对于那些比较,设置没有效果,总是表现为设置为ON 。如果说SET ANSI_NULLS OFF是没有影响的设置,那就更清楚了。

答案 1 :(得分:5)

如果@Region不是null值(假设@Region = 'South'),则不会返回Region字段为null的行,而不管ANSI_NULLS的值是什么。

ANSI_NULLS只会在@Region的值为null时产生差异,即当您的第一个查询基本上成为第二个查询时。

在这种情况下,ANSI_NULLS ON将不返回任何行(因为null = null将产生未知的布尔值(aka null))并且ANSI_NULLS OFF将返回Region字段为null的任何行(因为null = null会产生true

答案 2 :(得分:2)

SET ANSI_NULLS ON

IT返回表格中包含空值的所有值

SET ANSI_NULLS off

当列包含空值

时结束

答案 3 :(得分:1)

我想这里主要是:

从不用户:

  • @anything = NULL
  • @anything <> NULL
  • @anything != null

始终使用:

  • @anything IS NULL
  • @anything IS NOT NULL

答案 4 :(得分:0)

将ANSI NULLS设置为OFF将使NULL = NULL比较返回true。 EG:

        SET ANSI_NULLS OFF
        select * from sys.tables
        where principal_id = Null

将返回一些结果,如下所示: zcwInvoiceDeliveryType 744547 NULL zcExpenseRptStatusTrack 2099048 NULL ZCVendorPermissions 2840564 NULL ZCWOrgLevelClientFee 4322525 NULL

虽然此查询不会返回任何结果:

        SET ANSI_NULLS ON 
        select * from sys.tables
        where principal_id = Null

答案 5 :(得分:0)

https://docs.microsoft.com/en-us/sql/t-sql/statements/set-ansi-nulls-transact-sql

当SET ANSI_NULLS为ON时,即使column_name中存在空值,使用WHERE column_name = NULL的SELECT语句也会返回零行。使用WHERE column_name&lt;&gt;的SELECT语句即使column_name中存在非空值,NULL也会返回零行。

例如

DECLARE @TempVariable VARCHAR(10)
SET @TempVariable = NULL

SET ANSI_NULLS ON
SELECT 'NO ROWS IF SET ANSI_NULLS ON' where    @TempVariable = NULL
-- IF ANSI_NULLS ON , RETURNS ZERO ROWS


SET ANSI_NULLS OFF
SELECT 'THERE WILL BE A ROW IF ANSI_NULLS OFF' where    @TempVariable =NULL
-- IF ANSI_NULLS OFF , THERE WILL BE ROW !

答案 6 :(得分:-2)

如果ANSI_NULLS设置为&#34; ON&#34;如果我们申请=,&lt;&gt;在写入select语句时,在NULL列值上,它将不会返回任何结果。

示例

create table #tempTable(sn int,ename varchar(50))

插入#tempTable

选择1,&#39; Manoj&#39;

UNION ALL

选择2,&#39; Pankaj&#39;

UNION ALL

选择3,NULL

UNION ALL

选择4,&#39; Lokesh&#39;

UNION ALL

选择5,&#39; Gopal&#39;

SET ANSI_NULLS ON

从#tempTable中选择*,其中ename为NULL - (1行(s)受影响)

从#tempTable中选择*,其中ename = NULL - (0行(s)受影响)

从#tempTable中选择*,其中ename&lt;&gt; NULL - (0行(s)受影响)

SET ANSI_NULLS OFF

从#tempTable中选择*,其中ename为NULL - (1行(s)受影响)

从#tempTable中选择*,其中ename = NULL - (1行(s)受影响)

从#tempTable中选择*,其中ename不为NULL - (4行受影响)

从#tempTable中选择*,其中ename&lt;&gt; NULL - (4行(s)受影响)