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

StackOverflow https://stackoverflow.com/questions/203493

  •  03-07-2019
  •  | 
  •  

Вопрос

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

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

Это было полезно?

Решение

Я считаю, что ответ заключается в том, что Oracle очень и очень стар.

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

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

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

Другие советы

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

Zero длины варчар рассматривается как нулевая.

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

«При назначении в Чар (1) становится '' (типы символов - это пустые мягкие строки).

'' При назначении VARCHAR2 (1) становится '', которая представляет собой строку нулевой длины, а строка нулевой длины - нулевая в Oracle (это не длинное '')

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Обработка Oracle ссылок NULL:

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top