Соответствует ли эта реализация SQL-92?

Тони Эндрюс в другом вопрос дал пример:

IF p_c_courtesies_cd 
   || p_c_language_cd 
   || v_c_name 
   || v_c_firstname 
   || v_c_function 
   || p_c_phone 
   || p_c_mobile p_c_fax 
   || v_c_email is not null
THEN
     -- Do something
END IF;

в качестве умной (если не малопонятной) альтернативы функции Oracle COALESCE. Конечно, это работает, если какой-либо аргумент не равен нулю, проверка IF верна. Мой вопрос: соответствует ли реализация Oracle указанной выше операции конкатенации SQL-92? Разве выражение, содержащее NULL, не должно оцениваться как NULL? Если вы так не думаете, то почему выражение 1 + NULL должно оцениваться как NULL?

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
5
0
1 426
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ну, COALESCE явно определен стандартом SQL-92 для возврата первого ненулевого значения в списке; так что по определению реализация этого Oracle работает правильно.

Обновлено: Спецификация SQL-92; найдите COALESCE, чтобы увидеть его определение.

Тем не менее, в NULL нет ничего особенного, что заявляет, что любая операция, связанная с NULL, должна быть NULL. Более точное ограничение состоит в том, что NULL не является ни ложным, ни 0, ни равным другому NULL (например, NULL == NULL является ложным, потому что один NULL не равен другому NULL). Однако это не означает, что не может быть логически согласованных способов работы с NULL, которые не всегда возвращают NULL.

Обновлено: Итак, NULL + 1 равно NULL так же, как NaN + 1 по-прежнему NaN; это фактически неопределенная операция.

+1 за ссылку. Однако в стандарте, как я его читал, явно указывается, что результат конкатенации нулевого значения с чем-либо должен быть нулевым.

DCookie 20.01.2009 22:07

@DCookie: а, я думал, вы спрашиваете, соответствует ли реализация COALESCE стандарту. Однако я согласен, их реализация CONCATENATION НЕ соответствует стандарту, если для этого она возвращает не NULL.

nezroy 20.01.2009 22:26

Извините за то, что не разобрался, я предполагаю, что из приведенного мной примера я имел в виду операцию конкатенации :-(

DCookie 20.01.2009 23:56

Нет, наверное, в этом есть смысл, уверен, я просто просмотрел это слишком быстро :)

nezroy 21.01.2009 00:11
SQL>  select 'something'||null from dual;

'SOMETHIN
---------
something

конкатенация строки с нулем не приводит к нулю. Считаю это нормальным поведением, привык. Не знаю, что еще сказать.

Тот факт, что Oracle реализовал это таким образом, не означает, что это правильно.

DCookie 20.01.2009 21:47

Что-то правильно, когда все работает так, как описано в руководствах.

tuinstoel 20.01.2009 21:48

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

DCookie 20.01.2009 21:51

Я спрашиваю, соответствует ли он стандарту SQL. Извините, если это было непонятно.

DCookie 20.01.2009 21:53

Я не знаю, соответствует ли он стандарту SQL.

tuinstoel 20.01.2009 21:54

Добавлю, что PostgreSQL ведет себя стандартно: «SELECT 'something' || NULL;» возвращает NULL.

nezroy 20.01.2009 22:59

И MSSQL тоже ведет себя стандартно, даже несмотря на то, что они специально используют оператор «конкатенации строк»: «SELECT 'something' + NULL;» возвращает NULL.

nezroy 20.01.2009 23:02

@Nezroy: Спасибо за ссылку. Однако, читая стандарт, я считаю, что в нем говорится, что реализация Oracle на самом деле неверна. Раздел 6.13, Общие правила, пункт 2а:

     2) If <concatenation> is specified, then let S1 and S2 be the re-
        sult of the <character value expression> and <character factor>,
        respectively.

        Case:

        a) If either S1 or S2 is the null value, then the result of the
          <concatenation> is the null value.

Сначала я подумал, что вы спрашиваете, соответствует ли реализация COALESCE стандарту. Однако я согласен, их реализация CONCATENATION НЕ соответствует стандарту, если для этого она возвращает не NULL.

nezroy 20.01.2009 22:29

Да, мой вопрос был не совсем ясным. Мои извинения. По крайней мере, я знал, что я имел в виду ;-)

DCookie 20.01.2009 23:41

Основываясь на части спецификации SQL-92, выделенной DCookie, и поведении других БД, я бы сказал, что Oracle не ведет себя в соответствии со стандартом с их оператором конкатенации.

Oracle (из ответа Tuinstoel):

SQL>  select 'something'||null from dual;

'SOMETHIN
---------
something

MSSQL:

SELECT 'something'+NULL;

NULL

PostgreSQL:

postgres=# \pset null '(null)'
Null display is "(null)".
postgres=# select 'something'||null as output;
 output
--------
 (null)
(1 row)

MySQL:

mysql> select concat('something',NULL) as output;
+--------+
| output |
+--------+
| NULL   |
+--------+
1 row in set (0.00 sec)
Ответ принят как подходящий

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

Все начинается с того, что Oracle хранит строки со счетчиком символов, за которым следуют строковые данные. NULL представлен нулевым количеством символов без следующих строковых данных - что в точности совпадает с пустой строкой (''). Oracle просто не умеет их различать.

Это приводит к некоторому необычному поведению, например к этому случаю объединения. Oracle также имеет функцию LENGTH для возврата длины строки, но это было определено противоположным образом, так что LENGTH ('') возвращает NULL, а не ноль. Так:

LENGTH('abc') + LENGTH('') IS NULL

LENGTH('abc' || '') = 3

что, как мне кажется, нарушает основные математические принципы.

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

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