테이블에서 NULL 값 자체 비교


13

나는 항상 다음과 같은 신비한 t-sql 동작에 대해 의아해합니다.

-- Create table t and insert values.  
use tempdb
CREATE TABLE dbo.t (a INT NULL);  
-- insert 3 values
INSERT INTO dbo.t values (NULL),(0),(1);  
GO  
set ansi_nulls off -- purposely turn off, so we can allow NULL comparison, such as null = null
go
-- expect 3 rows returned but only 2 returned (without null value row)
select * from dbo.t where a = a 

이것은 테이블의 모든 행을 검색하는 방법이 아니라 ANSI_NULLS의 사용을 피하는 것이 아닙니다.

왜 t-sql이 이런 식으로 작동하는지 통찰력을 요구하고 싶습니다.

답변:


13

이것은 놀라운 동작이지만 MSDN 페이지 SET ANSI_NULLS에서 적어도 예상되는 동작임을 알 수 있습니다. 절대 사용하지 않는 한 가지 더 ANSI_NULLS OFF:

SET ANSI_NULLS비교의 피연산자 중 하나가 변수 NULL이거나 리터럴 인 경우에만 비교에 영향을줍니다 NULL. 비교의 양쪽이 열 또는 복합 표현식 인 경우 설정은 비교에 영향을 미치지 않습니다.


8

msdn 문서에서 명확하지 않을 수도 있지만 다음과 같은 사실을 알게 될 것입니다.

"SET ANSI_NULLS ON은 비교의 피연산자 중 하나가 NULL 또는 리터럴 NULL 인 경우에만 비교에 영향을줍니다. 비교의 양쪽이 열 또는 복합 표현식 인 경우 설정은 비교에 영향을 미치지 않습니다."

https : //.com/questions/2866714/how-does-ansi-nulls-work-in-tsql 참조


Scott과 ypercube에게 감사드립니다. 두 답변 모두이 행동의 요점에 해당하므로 두 답변을 모두 찬성했습니다.
jyao

Ypercube 먼저 :)했다
스콧 Hodgin

4

2015 년 다음 포스트의 Robert Sheldon은 NULL 동작과 왜 (항상 그런 것은 아니지만) 실패에 대해 설명합니다.

https://www.simple-talk.com/sql/t-sql-programming/how-to-get-nulls-horribly-wrong-in-sql-server/

그는 프로그래머가 쉽게 넘어갈 수있는 13 개의 NULL 실패를 설명합니다.

실패 # 1 : NULL의 의미를 모름

설명 : NULL은 값이 아닌 존재하지 않는 값입니다. 0이 아닙니다. 빈 문자열이 아닙니다. 값은 NULL과 같을 수 없습니다. 두 개의 NULL 값이 동일하지 않습니다 .

이것이 기본적인 문제이지만 다른 실패에 대해서도 읽어보십시오.

예. 이전 버전 (SQL Server 7 이전 버전)은 원하는 것과 더 다르게 작동했습니다.

그러나 스택 오버플로 및 스택 교환에서 문제를 검색하면 문제를 논의하는 많은 스레드가 있습니다.


3
로버트 셀던 (Robert Sheldon)의 링크 된 게시물을 한 번 읽었지만 (IMHO) 내 모범의 행동을 설명하는 이론이나 증거는 없습니다.
jyao

1
"2 개의 NULL 값이 동일하지 않습니다." OK. 그러나 ansi nulls가 꺼져있을 때 그 반대를 기대할 것입니다. 특히 WHERE NULL = NULL설정이 완료되면 수율이 적용 되기 때문 입니다.
ypercubeᵀᴹ

1

토론에 추가하기 위해 SQL92 표준의 NULL 정의를 모호하게 해석 할 수 있습니다. 다음 은 sqlite.org가 제공하는 다양한 DBMS 의 NULL 처리 및 해석에 대한 요약입니다 .

공개 : 위의 sqlite.org 페이지의 이전 버전 (예 : 6-8 년 전)에서 SQL92의 "모호성"에 대해 읽은 것을 기억하지만 그 페이지는 이후 업데이트되었습니다.

위의 RLF의 대답은 좋은 견적을 가지고,하지만 난 로버트 셀던에 동의하지 않는 경우 내가 (즉, "존재하지 않는 것을"고려하기 때문에 그것은 단지의 NULL는 ) 철학적으로하고 할을 영어-의미 뭔가 "에 해당하는 다른 존재하지 않는 ". 쉘던의 논리를 이해하려면 NULL의 정의 NULL 이라고 선언 할 수 있습니다 . (존재하지 않으면 어떻게 정의 할 수 있습니까? 소름 끼치 지요?)

러셀의 역설 양조 ( 두통) 변형을 봅니다 . :-\

그러나 이것은 영어 의미론 ( NO SQL)에 대한 논의이며 철학 토론은 여기에 속합니다 . :-)


추신 : 저는이 SE 커뮤니티를 처음 접했습니다. 이전에 광고 구역 에 대해 논의한 적이 있으면 사과드립니다.
pr1268

1
표준의 모호성은 어디에 있습니까?
ypercubeᵀᴹ

@ ypercubeᵀᴹ : 나는 애매 모호함이 3VL 을 불리언 에 "적합"시키려는 시도에 있다고 생각한다 . NULL 비교를 통한 테이블 조인 은 여러 가지 다른 방식으로 해석 될 수 있습니다.
pr1268

불일치에 대해서는 동의하지만 모호함에 대해서는 동의하지 않습니다.
ypercubeᵀᴹ

1
@ ypercubeᵀᴹ : 충분합니다 ... 위에서 링크 한 sqlite.org 페이지의 이전 버전이 말한 내용 만 인용하고있었습니다 ( "SQL92는 NULL 처리 및 해석과 관련하여 모호합니다"또는 매우 유사한 것). 그러나 나는 논쟁하지 않는다. 아마도 sqlite.org 페이지 자체가 오해의 소지가 있거나 잘못되었습니다. 아마도 업데이트 된 이유를 설명합니다.
pr1268
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.