[sql] Oracle 9i가 빈 문자열을 NULL로 취급하는 이유는 무엇입니까?

나는 그것이 알고 않는 으로 ‘고려 NULL하지만 나에게 많은 일을하지 않는 이유는 이 경우이다. SQL 사양을 이해함에 따라 ”는 같지 않습니다. NULL하나는 유효한 데이텀이고 다른 하나는 동일한 정보가 없음을 나타냅니다.

자유롭게 추측하되, 그 경우에 표시하십시오. 오라클의 누군가가 그것에 대해 의견을 말할 수 있다면 환상적입니다!



답변

답은 오라클이 매우 오래되었다는 것입니다.

예전에는 SQL 표준이 존재하기 전인 오라클은 빈 열의 문자열 VARCHAR/ VARCHAR2열이 NULLNULL이고 단 하나의 NULL 만 있다는 설계 결정을 내 렸습니다 . 답변이 존재하지만 사용자에 의해 알려지지 않은 데이터, 답변이없는 데이터 등은 모두 어떤 의미를 갖습니다 NULL).

SQL 표준이 등장 NULL하고 빈 문자열이 별개의 엔터티라는 데 동의했을 때 이미 두 사용자가 동등한 것으로 가정 한 코드를 가진 Oracle 사용자가있었습니다. 따라서 Oracle은 기본적으로 기존 코드를 깨거나 SQL 표준을 위반하거나 잠재적으로 많은 수의 쿼리 기능을 변경하는 일종의 초기화 매개 변수를 도입하는 옵션이 남아있었습니다. SQL 표준 (IMHO)을 위반하는 것이이 세 가지 옵션 중에서 가장 파괴적이었습니다.

오라클은 VARCHAR향후 릴리스에서 SQL 표준을 준수하기 위해 데이터 유형이 변경 될 가능성을 열어 놓았습니다 (그래서 VARCHAR2해당 데이터 유형의 동작이 계속 동일하게 유지되기 때문에 모든 사람 이 Oracle에서 사용하는 이유 ).


답변

Tom Kyte 오라클 부사장 :

ZERO 길이 varchar는 NULL로 처리됩니다.

”는 NULL로 취급되지 않습니다.

”는 char (1)에 할당 될 때 ”가됩니다 (문자 유형은 공백으로 채워진 문자열입니다).

”varchar2 (1)에 할당되면 ”는 길이가 0 인 문자열이고 길이가 0 인 문자열은 Oracle에서 NULL입니다 (더 이상은 아닙니다)


답변

필자는 초기 개발자가했던 방식대로 Oracle을 데이터 입력 시스템의 영광스러운 백엔드로 생각하면 이것이 더 의미가 있다고 생각합니다. 데이터베이스의 모든 필드는 데이터 입력 운영자가 화면에서 본 양식의 필드에 해당합니다. 운영자가 “생년월일”또는 “주소”에 관계없이 필드에 아무것도 입력하지 않은 경우 해당 필드의 데이터는 “알 수 없음”입니다. 운영자가 누군가의 주소가 실제로 빈 문자열임을 나타낼 방법이 없으며, 어쨌든 그다지 의미가 없습니다.


답변

Oracle 설명서는 개발자에게이 문제에 대해 경고하며 최소한 버전 7까지 거슬러 올라갑니다.

오라클은 “불가능한 값”기술로 NULLS를 나타내기로 결정했습니다. 예를 들어, 숫자 위치의 NULL은 불가능한 값인 “마이너스 0″으로 저장됩니다. 계산 결과 마이너스 0은 저장되기 전에 양의 0으로 변환됩니다.

또한 Oracle은 길이가 0 인 VARCHAR 문자열 (빈 문자열)을 불가능한 값으로 간주하고 NULL을 표시하기에 적합한 선택으로 잘못 선택했습니다. 빈 문자열은 불가능한 값과 거리가 멀다는 것이 밝혀졌습니다. 문자열 연결 작업의 정체성이기도합니다!

Oracle 설명서는 데이터베이스 설계자와 개발자에게 향후 버전의 Oracle이 빈 문자열과 NULL 사이에서이 연관을 해제하고 해당 연관에 종속 된 코드를 손상시킬 수 있다고 경고합니다.

불가능한 값 이외의 NULLS 플래그를 지정하는 기술이 있지만 Oracle은이를 사용하지 않았습니다.

(위의 “location”이라는 단어를 사용하여 행과 열의 교차점을 의미합니다.)


답변

빈 문자열은 두 문자열 (빈 문자열과 null)이 동일하지 않은 상황과 비교할 때 “더 적은 악”으로 인해 단순히 NULL과 동일합니다.

NULL과 빈 문자열이 같은 언어에서는 항상 두 조건을 모두 확인해야합니다.


답변

공식 11g 문서에 따르면

Oracle Database는 현재 길이가 0 인 문자 값을 널로 처리합니다. 그러나 이것은 향후 릴리스에서 계속 적용되지 않을 수 있으므로 빈 문자열을 null과 동일하게 처리하지 않는 것이 좋습니다.

가능한 이유

  1. val IS NOT NULL 보다 읽기 쉽다 val != ''
  2. 두 조건을 모두 확인할 필요가 없습니다 val != '' and val IS NOT NULL

답변

책의 예

   set serveroutput on;
    DECLARE
    empty_varchar2 VARCHAR2(10) := '';
    empty_char CHAR(10) := '';
    BEGIN
    IF empty_varchar2 IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('empty_varchar2 is NULL');
    END IF;


    IF '' IS NULL THEN
    DBMS_OUTPUT.PUT_LINE(''''' is NULL');
    END IF;

    IF empty_char IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('empty_char is NULL');
    ELSIF empty_char IS NOT NULL THEN
    DBMS_OUTPUT.PUT_LINE('empty_char is NOT NULL');
    END IF;

    END;