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

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

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

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

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

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

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



[Тома Кайт](https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:5984520277372) вице-президент 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](https://docs.oracle.com/cd/B28359_01/server.111/b28286/sql_elements005.htm)

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