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

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

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

Не стесняйтесь размышлять? Почему-то я не думаю, что это даст вам наибольший набор ответов ..

SCdF 15.10.2008 06:29

Думаю, нет, но я не был уверен, что по этому поводу есть определенность, поэтому решил, что распахну двери. Кажется, пока что все получилось хорошо.

Chris R 15.10.2008 07:11
docs.oracle.com/database/121/SQLRF/…
Jayan 16.09.2014 14:07

Связанный: dba.stackexchange.com/q/49744/56961

AlikElzin-kilaka 21.04.2016 09:31
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
219
4
70 024
10
Перейти к ответу Данный вопрос помечен как решенный

Ответы 10

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

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

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

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

недопустимые значения времени данных? Не уверен, что это значит. Вы разместили это здесь как вопрос?

Mark Brady 15.10.2008 19:17

Проблема возникла раньше, чем stackoverflow - я не получил полезной информации на форумах Oracle, и я создал обходной путь - я отслежу свои заметки и опубликую здесь.

Cade Roux 15.10.2008 19:56

Выложил подробности в виде вопроса здесь.

Cade Roux 15.10.2008 20:13
Ответ принят как подходящий

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

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

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

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

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

A ZERO length varchar is treated as NULL.

'' is not treated as NULL.

'' when assigned to a char(1) becomes ' ' (char types are blank padded strings).

'' when assigned to a varchar2(1) becomes '' which is a zero length string and a zero length string is NULL in Oracle (it is no long '')

Вау, Том довольно язвительный. Учитывая, что вопросы относятся к вопиющему расхождению с SQL92, можно подумать, что он будет менее настойчив в этом вопросе ... хотя, возможно, он устал отвечать.

Chris R 15.10.2008 07:10

Лучшее в Томе - это то, что вы получаете четкий ответ, в котором точно заявляет, что он думает. Поищите некоторые комментарии, в которых люди использовали текстовые сообщения, на сайте "Спросите Тома"

Chris Gill 27.08.2009 16:17

Но точнее было бы, если бы вторую строку поменяли на '' не всегда обрабатывается как NULL.

ypercubeᵀᴹ 05.07.2011 11:48

@ypercube Цитата не станет более точной, если изменить слово, которое фактически использовал Том. Если вы думаете, что Том сформулировал это запутанно, ммм. Может быть. Я думаю, что он место на. Наиболее запутанные ситуации возникают, когда '' преобразуется косвенно в VARCHAR2, например, cast('' as char(1)) is null, который ... на удивление ИСТИННЫЙ

sehe 19.07.2013 19:17

@sehe сбивающий с толку бит для меня - выбрать 1 из двойного, где ('' равно нулю)

matt freake 22.08.2013 19:58

Я ожидаю, что '' не будет рассматриваться как NULL буквальные строки - это символы, а не варчары. Логика. Но почему тогда следующий запрос возвращает ноль строк? select 1 as one from dual where 'a' > '' or 'a' < ''

Patrick Fromberg 28.03.2014 22:29

Поскольку любое сравнение со значением NULL не возвращает ни TRUE, ни FALSE, а UNKNOWN ... и UNKNOWN OR UNKNOWN является UNKNOWN и никогда не будет оправдывать условие where. Вы можете легко проверить это, окружив все свое условие where с помощью NOT (...), и оно все равно даст 0 строк ;-)

Falco 06.05.2014 19:24

@Falco, вокруг которого идет обсуждение '' рассматривается как ноль. Не поведение нулевого значения.

Brian 06.05.2014 22:59

Но если Патрик ожидает, что '' будет рассматриваться как NULL, почему он удивлен, что это ЖЕ поведение, как фактическое значение NULL? Результат его строки будет таким же, независимо от того, помещает ли он туда '' или NULL.

Falco 07.05.2014 19:44

'' is not treated as NULL. Неправильно, на моем Oracle 11.2 следующий код печатает null: if '' is null then SYS.DBMS_OUTPUT.PUT_LINE('null');end if;

Roland 27.05.2015 19:51

@Roland - в контексте он говорил, что '' не рассматривается как нулевой в любой ситуации. В следующей строке приведен пример, когда присвоение его char запускало его поведение пустого заполнения (хотя char также может иметь значение NULL). Я предполагаю, что компилятор PL / SQL следует семантике varchar2, когда встречает нетипизированный ''.

William Robertson 07.12.2016 18:41

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

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

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

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

Есть способы пометить NULLS, отличные от невозможных значений, но Oracle их не использовал.

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

Документация Oracle предупреждает проектировщиков и разработчиков баз данных, что некоторая будущая версия Oracle может нарушить эту связь между пустой строкой и NULL и нарушить любой код, который зависит от этой связи. – could you please provide reference for this statement?
Piotr Dobrogost 15.10.2018 23:44
docs.oracle.com/cd/B19306_01/server.102/b14200/…
Walter Mitty 16.10.2018 03:29

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

Это имеет смысл только в том случае, если вы предполагаете, что каждое поле в системе ввода данных является обязательным. Отсутствие ответа на необязательное поле (например, «Имя собаки») является допустимым, поэтому пустая строка по-прежнему имеет цель, отличную от NULL. Даже с учетом этого предположения я сомневаюсь, что первые разработчики думали об Oracle как о «прославленном бэкэнде для системы ввода данных», поэтому я не уверен, что этот ответ вообще имеет смысл.

Jared 13.11.2015 22:07

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

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

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

Намного, намного проще отлаживать. Кроме того, если вы видите пустую ячейку или ввод на экране, вы знаете, что данные в БД равны нулю. В других БД, где '' <> NULL, вы не можете «увидеть», являются ли данные нулевыми или '', это приводит к очень скрытым ошибкам. '' = null это самый разумный вариант, даже если он нестандартный.

Lucio M. Tato 19.10.2013 00:02

«В других БД, где '' <> NULL, вы не можете« увидеть », являются ли данные нулевыми или ''” => Обычно инструменты БД отображают NULL иначе, чем пустые строки. Фактически, даже Oracle SQL Developer показывает NULL как «(null)». Я предполагаю, что это нужно для того, чтобы отличить NULL от пробелов, но это не связано с разницей между NULL и пустыми строками.

Didier L 23.09.2014 18:18

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

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

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

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

Цитата, необходимая для проведения различия между «пустой строкой» и значением NULL. В любой базе данных, кроме Oracle, поле VARCHAR может иметь значение (ноль или более символов) или не иметь значения (NULL), точка.

user565869 09.07.2014 18:27

«Пять или шесть лет назад» с 2011 года попадает в временные рамки 10g (10,1 выпущено в 2003 году, 10,2 - в 2005 году). 10g абсолютно не вносил никаких глобальных изменений в обработку нулевых значений, и никогда не было никакого различия между NULL и строкой с нулевым значением, и такое различие не имеет смысла. Боюсь, этот ответ - полная фантазия.

William Robertson 21.07.2018 13:34

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

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

Просто установите ограничение not null для своего столбца и проверяйте только пустую строку.

Egor Skriptunoff 30.06.2013 03:27

Проверка обоих условий тривиальна: WHERE Field <> '' возвращает истину, только если поле не равно NULL и не пусто, в базах данных с поведением ANSI для пустых строк.

user565869 09.07.2014 18:24

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

Oracle Database currently treats a character value with a length of zero as null. However, this may not continue to be true in future releases, and Oracle recommends that you do not treat empty strings the same as nulls.

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

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

В полностью совместимой с ANSI базе данных вам не нужно проверять оба условия. val <> '' уже исключает NULL. Возможно вы имели в виду val = '' OR val IS NULL. Но пустые строки, которые не сравниваются как NULL, - это полезный!

ErikE 03.02.2016 19:02

Я согласен со сравнительной частью.

Sorter 26.06.2019 08:44

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

   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;

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