SQL Server에서 "SET ANSI_NULLS ON"은 무엇을 의미합니까?


92

정의에 따르면 :

SET ANSI_NULLS가 ON이면 WHERE column_name = NULL을 사용하는 SELECT 문은 column_name에 null 값이 있더라도 0 행을 반환합니다. WHERE column_name <> NULL을 사용하는 SELECT 문은 column_name에 null이 아닌 값이 있더라도 0 행을 반환합니다.

이 쿼리에 null이 포함되지 않음을 의미합니까?

SELECT Region
FROM employees
WHERE Region = @region

아니면이 ANSI_NULL같은 쿼리에만 관련이 있습니까 (여기 WHERE에 특정 단어 가 포함됨 NULL)?

SELECT Region
FROM employees
WHERE Region = NULL

1
첫 번째 단락을 복사 한 공식 문서의 네 번째 단락에 아직 답변이 없습니까?-> "SET ANSI_NULLS ON은 비교 피연산자 중 하나가 NULL 인 변수 인 경우에만 비교에 영향을 미칩니다. 또는 리터럴 NULL. 비교의 양쪽이 열 또는 복합 표현식 인 경우 설정은 비교에 영향을주지 않습니다. "
user1451111

답변:


68

즉 , 첫 번째 예에서 사용 하면 @regionis NULL인 경우 테이블에 Region가 있는 행이 있더라도 행이 반환되지 않습니다 NULL.

ANSI_NULLS이 on 일 때 (항상 설정해야합니다.이 옵션을 사용하지 않는 옵션은 향후 제거 될 예정이므로), 피연산자 중 하나가 (적어도) 하나의 비교 연산 NULL이 세 번째 논리 값을 생성합니다- UNKNOWN( 반대로 TRUE하고 FALSE).

UNKNOWN그들은 이미 (예를 들어 결정하지 않는 경우 값이 어떤 조합 부울 연산자를 통해 전파 ANDFALSE피연산자 또는 ORTRUE피연산자) 또는 부정 ( NOT).

WHERE절에 의해 생성 된 결과 세트를 필터링하는 데 사용되는 FROM절의 전반적인 값이되도록 WHERE절이어야 TRUE하는 행에 대한 필터링 할 수 없다. 따라서 UNKNOWN어떤 비교에 의해 생성되는 경우 행이 필터링됩니다.


@ user1227804의 답변 에는 다음 인용문이 포함됩니다.

비교의 양쪽이 모두 열 또는 복합 표현식 인 경우 설정은 비교에 영향을주지 않습니다.

에서 *SET ANSI_NULLS

그러나 두 NULL열을 비교하면 (예 : a 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. 그리고에 대한 문서= 에는 피연산자에 대해 말할 것이 없습니다.

NULL표현식 을 비교할 때 결과는 ANSI_NULLS설정에 따라 다릅니다 .

가로 ANSI_NULLS설정된 경우 ON결과는 NULL1 이며 NULL(또는 알 수없는) 값이 다른 NULL값이나 알 수없는 값 과 같지 않다는 ANSI 규칙을 따릅니다 .

가로 ANSI_NULLS설정된 경우 비교 OFF결과 는 입니다.NULLNULLTRUE

NULL이 아닌 것과 비교하면 NULL항상 FALSE2가 됩니다.

그러나 12 는 모두 정확하지 않습니다 UNKNOWN. 두 비교 결과는 모두입니다 .


* 이 텍스트의 비밀스러운 의미는 몇 년 후 마침내 발견되었습니다. 실제로 의미하는 것은 이러한 비교의 경우 설정이 효과가 없으며 항상 설정이 ON 인 것처럼 작동한다는 것 입니다. 그것이 SET ANSI_NULLS OFF영향을 미치지 않는 설정이라고 언급했다면 더 분명했을 것 입니다.


1
그래서 내가 당신을 옳게 이해한다면, "Where Region = @region"구절의 결과에도 영향을 미치고 "Where Region = null"을 구체적으로 쓸 때뿐만 아니라?
Rodniko 2012 년

7

@Region이 아닌 경우 null(라고 말하면 @Region = 'South') ANSI_NULLS 값에 관계없이 Region 필드가 null 인 행을 반환하지 않습니다.

ANSI_NULLS는의 값이 인 @Region경우 null, 즉 첫 번째 쿼리가 본질적으로 두 번째 쿼리가되는 경우에만 차이를 만듭니다 .

이 경우 ANSI_NULLS ON은 행을 반환하지 않으며 ( null = null알 수없는 부울 값 (일명 null) 을 생성 하기 때문에 ) ANSI_NULLS OFF는 Region 필드가 null 인 모든 행을 반환합니다 ( null = null를 생성 하기 때문에 true).


6

ANSI_NULLS가 "ON"으로 설정되고 select 문을 작성하는 동안 NULL 열 값에 =, <>를 적용하면 결과가 반환되지 않습니다.

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

insert into #tempTable
values (1, 'Manoj'), (2, 'Pankaj'), (3, NULL), (4, 'Lokesh'), (5, 'Gopal')

ANSI_NULLS 설정

select * from #tempTable where ename is NULL -- (1 row(s) affected)
select * from #tempTable where ename = NULL -- (0 row(s) affected)
select * from #tempTable where ename is not NULL -- (4 row(s) affected)
select * from #tempTable where ename <> NULL -- (0 row(s) affected)

ANSI_NULLS 설정 해제

select * from #tempTable where ename is NULL -- (1 row(s) affected)
select * from #tempTable where ename = NULL -- (1 row(s) affected)
select * from #tempTable where ename is not NULL -- (4 row(s) affected)
select * from #tempTable where ename <> NULL -- (4 row(s) affected)

2
유일한 해답 인을위한 하나는 분명하게 구별 WHERE X IS NULL하고 WHERE X = NULL, 그리고 ANSI_NULLS가 결과에 영향을 미치는 방법에 대해 설명합니다. 열렬한 반대 투표자들의 시도에도 불구하고, 이것이 받아 들여진 대답이어야합니다!
Riegardt Steyn

1
예를 사용하여 설명하는 +1은 긴 문장보다 항상 더 명확하고 간결합니다.
peter.aryanto

3

ANSI_NULLS 설정

IT는 테이블의 null 값을 포함한 모든 값을 반환합니다.

ANSI_NULLS 설정 해제

열에 널값이 포함되면 종료됩니다.


2
이 답변은 이미 명시된 답변에 어떤 추가 사항을 추가합니까? 오래된 질문에 새로운 해답을 추가 조심해야 - 그들은 새로운 통찰력을 이미 게시 솔루션을 확장 explaination를 포함하거나 제공해야한다 - 검토에서
Takarii

1

여기서 가장 중요한 것은 다음과 같습니다.

절대의 사용자 :

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

항상 사용 :

  • @anything IS NULL
  • @anything IS NOT NULL

0

ANSI NULLS를 OFF로 설정하면 NULL = NULL 비교가 true를 반환합니다. 예 :

        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

0

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

SET ANSI_NULLS가 ON이면 WHERE column_name = NULL을 사용하는 SELECT 문은 column_name에 null 값이 있더라도 0 행을 반환합니다. WHERE column_name <> NULL을 사용하는 SELECT 문은 column_name에 Null이 아닌 값이 있더라도 0 행을 반환합니다.

예를 들어

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 !
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.