Почему Oracle 9i обрабатывает пустую строку как NULL? - PullRequest
203 голосов
/ 15 октября 2008

Я знаю, что считает '' NULL, но это мало что говорит мне почему это так. Как я понимаю в спецификациях SQL, '' - это не то же самое, что NULL - одна является допустимой датумом, а другая указывает на отсутствие этой же информации.

Не стесняйтесь спекулировать, но, пожалуйста, укажите, так ли это. Если бы кто-нибудь из Oracle мог прокомментировать это, это было бы здорово!

Ответы [ 10 ]

208 голосов
/ 15 октября 2008

Я полагаю, что ответ таков: Оракул очень, очень стар.

В прежние времена, когда существовал стандарт SQL, Oracle приняла решение о том, что пустые строки в столбцах VARCHAR / VARCHAR2 равны NULL и что существует только одно значение NULL (существуют теоретики отношений которые будут различать данные, которые никогда не запрашивались, данные, где ответ существует, но не известен пользователю, данные, где ответа нет, и т. д., все из которых составляют некоторый смысл NULL).

К тому времени, когда стандарт SQL пришел и согласился с тем, что NULL и пустая строка - это разные сущности, уже были пользователи Oracle, у которых был код, который предполагал, что эти два значения эквивалентны. Таким образом, у Oracle остались возможности нарушить существующий код, нарушить стандарт SQL или ввести какой-либо параметр инициализации, который изменит функциональность потенциально большого количества запросов. Нарушение стандарта SQL (IMHO) было наименее разрушительным из этих трех вариантов.

Oracle оставила открытой возможность того, что тип данных VARCHAR изменится в будущем выпуске, чтобы соответствовать стандарту SQL (именно поэтому все используют VARCHAR2 в Oracle, поскольку поведение этого типа данных гарантированно останется таким же иду вперед).

56 голосов
/ 15 октября 2008

Том Кайт Вице-президент Oracle:

VARCHAR нулевой длины рассматривается как NULL.

'' не обрабатывается как NULL.

'' при назначении на символ (1) становится '' (типы символов пустые строки).

'' при назначении на varchar2 (1) становится '', который имеет нулевую длину строка и строка нулевой длины NULL в Oracle (это не долго '')

19 голосов
/ 18 февраля 2009

Я подозреваю, что это имеет больше смысла, если вы думаете об Oracle так, как это делали более ранние разработчики - как о прославленном бэкенде для системы ввода данных. Каждое поле в базе данных соответствовало полю в форме, которую оператор ввода данных видел на своем экране. Если оператор ничего не вводил в поле, будь то «дата рождения» или «адрес», тогда данные для этого поля «неизвестны». Оператор не может указать, что чей-то адрес действительно является пустой строкой, и в любом случае это не имеет особого смысла.

17 голосов
/ 15 октября 2008

Документация Oracle предупреждает разработчиков об этой проблеме, начиная с версии 7.

Oracle решила представлять NULLS методом "невозможного значения". Например, значение NULL в числовом месте будет сохранено как «минус ноль», невозможное значение. Любые минус нули, возникающие в результате вычислений, будут преобразованы в положительный ноль перед сохранением.

Oracle также по ошибке принял решение считать строку VARCHAR нулевой длины (пустую строку) невозможным значением и подходящим выбором для представления значения NULL. Оказывается, пустая строка далека от невозможного значения. Это даже тождество под операцией конкатенации строк!

Документация Oracle предупреждает разработчиков и разработчиков баз данных о том, что некоторые будущие версии Oracle могут разорвать эту связь между пустой строкой и NULL и разорвать любой код, который зависит от этой ассоциации.

Существуют методы для пометки NULL, кроме невозможных значений, но Oracle их не использовал.

(я использую слово «местоположение» выше для обозначения пересечения строки и столбца.)

2 голосов
/ 05 июня 2013

Пустая строка такая же, как NULL, просто потому, что это «меньшее зло» по сравнению с ситуацией, когда два (пустая строка и ноль) не совпадают.

В языках, где NULL и пустая строка не совпадают, необходимо всегда проверять оба условия.

0 голосов
/ 08 августа 2015

Пример из книги

   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;
0 голосов
/ 23 марта 2015

Согласно официальным документам 11 г

База данных Oracle в настоящее время обрабатывает символьное значение с нулевой длиной как ноль. Однако в будущих выпусках это может не соответствовать действительности, и Oracle рекомендует не рассматривать пустые строки так же, как пустые.

Возможные причины

  1. val IS NOT NULL более читабельно, чем val != ''
  2. Нет необходимости проверять оба условия val != '' and val IS NOT NULL
0 голосов
/ 14 июля 2011

Прежде всего, нулевые и нулевые строки не всегда рассматривались Oracle как одинаковые. Нулевая строка по определению является строкой, не содержащей символов. Это совсем не то же самое, что ноль. NULL, по определению, отсутствие данных.

Пять или шесть лет назад Oracle считала, что нулевая строка отличается от нулевой. В то время как, как и ноль, нулевая строка была равна всему и отличалась от всего (что я думаю, хорошо для нулевой, но совершенно НЕПРАВИЛЬНО для нулевой строки), по крайней мере длина (нулевая строка) вернет 0, как и должно быть, так как нулевая строка строка нулевой длины.

В настоящее время в Oracle length (null) возвращает значение null, которое, я думаю, равно O.K., но length (null string) также возвращает значение null, что совершенно НЕПРАВИЛЬНО.

Я не понимаю, почему они решили начать обрабатывать эти 2 разных "значения" одинаково. Они означают разные вещи, и программист должен иметь возможность действовать по-разному. Тот факт, что они изменили свою методологию, говорит мне, что они действительно не имеют ни малейшего представления о том, как эти значения должны обрабатываться.

0 голосов
/ 09 апреля 2010

Потому что не рассматривать его как NULL тоже не особо полезно.

Если вы допустили ошибку в этой области в Oracle, вы обычно сразу замечаете это. Однако на сервере SQL он будет работать, и проблема возникает только тогда, когда кто-то вводит пустую строку вместо NULL (возможно, из клиентской библиотеки .net, где null отличается от "", но вы обычно относитесь к ним одинаково. ).

Я не говорю, что Oracle прав, но мне кажется, что оба пути примерно одинаково плохи.

0 голосов
/ 15 октября 2008

Действительно, у меня не было ничего, кроме трудностей в работе с Oracle, включая недопустимые значения даты и времени (не могут быть напечатаны, преобразованы или что-то еще, только просмотр с помощью функции DUMP ()), которые позволяют вставлен в базу данных, видимо, через какую-то ошибочную версию клиента в виде двоичного столбца! Так много для защиты целостности базы данных!

Oracle обрабатывает ссылки NULL:

http://digitalbush.com/2007/10/27/oracle-9i-null-behavior/

http://jeffkemponoracle.com/2006/02/empty-string-andor-null.html

...