В PostgreSQL и Oracle, когда NULL и пустая строка обрабатываются одинаково? - PullRequest
0 голосов
/ 29 сентября 2018

Я создал следующий dbfiddle, в котором вы можете видеть, что field <> '' исключает случай, когда field равно нулю.

https://www.db -fiddle.com / f / xdfayYMvdRZDRRASvGFdpT / 0

CREATE TABLE test (
  prd_typ_cd bpchar,
  prd_prnt_typ_cd bpchar,
  prd_chld_typ_cd bpchar
);
INSERT INTO test VALUES ('SHC', null, 'DIV');

INSERT INTO test VALUES ('DIV', 'SHC', 'DEP');

INSERT INTO test VALUES ('DEP', 'DIV', null);

SELECT * FROM test WHERE prd_chld_typ_cd <> '';

Я был удивлен, увидев это, поскольку в большинстве языков NULL и '' (пустая строка) обрабатываются по-разному.

Приведенный выше пример взят из базы данных PostgreSQL.Будет ли то же самое верно для базы данных Oracle?При каких обстоятельствах PostgreSQL и Oracle рассматривают NULL и '' (пустую строку) как одно и то же?

Ответы [ 2 ]

0 голосов
/ 30 сентября 2018

Я не знаю о postgres, но у oracle есть некоторые причуды относительно пустых строк, о которых нужно знать, если вы планируете поддерживать их в своих приложениях: 1. в Oracle пустая строка ВСЕГДА считается NULL: если вывставьте пустую строку, вы будете читать обратно NULL.В oracle пустая строка просто не существует: это просто «сахар синтаксиса языка», если вы можете писать '' вместо NULL, когда имеете дело со значениями varchar.2. В Oracle значение '' null 'будет оцениваться как TRUE.пустая строка - DE FACTO null 3. В oracle любое сравнение, включающее значение NULL, ВСЕГДА будет оцениваться как ЛОЖЬ.это означает, что единственные операторы, которые вы можете применить к значениям NULL и которые могут возвращать TRUE, это «is null» и «not null»

Следствием вышесказанного является то, что в oracle ВСЕ следующие выражения будутоценивать в FALSE, независимо от фактического значения myvar:

 myvar = '' 
 myvar <> '' 
 myvar = null
 myvar <>null

, даже если они всегда оцениваются как false

 null = null
 null<>null
 null = '' 
 null <> '' 

, поэтому следующее обновление ничего не обновит:

Обновите mytab set myfield = 'X', где myfield = ''

, как я уже сказал, вы можете использовать только операторы 'is null' и 'is not null'.поэтому вы должны записать его как

update mytab set myfield = 'X', где myfield равно нулю.

PS Единственная функция оракула, которая рассматривает нуль как отдельное сопоставимое значение, это Decode ().возможно, это было ошибкой, но сегодня слишком много программного обеспечения, которое полагается на такое поведение, чтобы исправить это.

  decode( <expression>,
          <caseval 1>,  < exitval 1>,
          <caseval 2>,  < exitval 2>,
          .... 
           <elseval>) 

является старой реализацией конструкции sql case ... oracle обрабатывает NULL (так же как и пустые строки) как сопоставимые значения в этой функции.так что вы можете использовать NULL для и он будет соответствовать нулевым значениям (и пустым строкам).Это единственный случай, когда это происходит.

, если вы попытаетесь сделать это с помощью стандартной конструкции SQL Case, это не сработает: oracle не повторил ошибку там.

P.S: извините, если ответ будет выглядеть странно отформатированным.Я пишу со своего мобильного телефона ...

0 голосов
/ 29 сентября 2018

NULL и '' ARE обрабатываются по-разному в Postgres.

 prd_chld_typ_cd <> ''

возвращает NULL, когда prd_chld_typ_cd равно NULL,Это типичное поведение для большинства операций, включающих NULL.Вы легко обнаружите, что:

 prd_chld_typ_cd = ''

ведет себя точно так же, когда этот столбец равен NULL.

Для любого другого значения выражение возвращает значение true или false.Вы бы легко это увидели, если бы вернули значение:

SELECT t.*, prd_chld_typ_cd <> ''
FROM test t;

В результате NULL и false обрабатываются одинаково в WHERE фильтре - оба отфильтровывают строку.

Напротив, NULL и '' являются синонимами в Oracle.Но оказывается, что

 prd_chld_typ_cd <> ''
 prd_chld_typ_cd = ''

Оба ведут себя одинаково, когда prd_chld_typ_cd равно NULL.Увы, однако, в Oracle оба всегда возвращают NULL - потому что '' эквивалентно NULL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...