Почему Oracle 9i обрабатывает пустую строку как NULL?

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

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

10 ответов


Я считаю, что ответ в том, что Oracle очень, очень старый.

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

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

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


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

нулевая длина varchar рассматривается как НОЛЬ.

" не рассматривается как NULL.

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

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


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


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

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

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

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

существуют методы флаговые нули, отличные от невозможных значений, но Oracle их не использовала.

(Я использую слово "местоположение" выше, чтобы означать пересечение строки и столбца.)


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

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


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

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

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


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

база данных Oracle в настоящее время обрабатывает символьное значение с длиной нуля как null. Однако это может не сохраниться в будущих выпусках, и Oracle рекомендует не обрабатывать пустые строки так же, как 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;

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

обработка нулей Oracle ссылки:

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

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


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

пять или шесть лет назад нулевая строка обрабатывалась Oracle иначе, чем null. Хотя, как и null, null string была равна всему и отличалась от всего (что я думаю, хорошо для null, но совершенно неправильно для null string), по крайней мере length(null string) вернет 0, так как null string является строкой нулевой длины.

В настоящее время в Oracle length(null) возвращает null, который, я думаю, в порядке, но length(null string) также возвращает null, что совершенно неправильно.

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