Почему x IS NOT NULL
не равно NOT x IS NULL
?
Этот код:
CREATE TABLE bug_test (
id int,
name text
);
INSERT INTO bug_test
VALUES (1, NULL);
DO $$
DECLARE
v_bug_test bug_test;
BEGIN
RAISE NOTICE '%: %', v_bug_test, (v_bug_test IS NULL);
RAISE NOTICE '%: %', v_bug_test, (v_bug_test IS NOT NULL);
RAISE NOTICE '%: %', v_bug_test, (NOT v_bug_test IS NULL);
SELECT *
INTO v_bug_test
FROM bug_test
WHERE id = 1;
RAISE NOTICE '%: %', v_bug_test, (v_bug_test IS NULL);
RAISE NOTICE '%: %', v_bug_test, (v_bug_test IS NOT NULL);
RAISE NOTICE '%: %', v_bug_test, (NOT v_bug_test IS NULL);
END
$$;
DROP TABLE bug_test;
дает следующий вывод:
(,): t
(,): f
(,): f
(1,): f
(1,): f ???
(1,): t
в то время как я ожидал бы получить этот вывод:
(,): t
(,): f
(,): f
(1,): f
(1,): t <<<
(1,): t
postgresql
null
индиго
источник
источник
id
в своей реальной базе кода, но только после нескольких часов поиска проблемы.rec_variable IS NOT NULL
проверяет, все ли столбцы НЕ NULL, в то времяrec_variable IS NULL
как проверяет, все ли столбцы NULL. ОтсюдаNOT rec_variable IS NULL
дает то, что я ожидал - ответ на вопрос «есть ли что-нибудь внутри?».Ответы:
Вы должны различать две ситуации: вы сравниваете одну СТОЛБЦУ с NULL или сравниваете всю строку (RECORD) с NULL.
Рассмотрим следующий запрос:
Вы получаете это:
Это, я думаю, то, что вы и я ожидали бы. Вы проверяете одну КОЛОННУ против NULL и получаете «txt IS NOT NULL» и «NOT txt IS NULL» эквивалентны.
Однако, если вы делаете другую проверку:
Тогда вы получите
Это может быть удивительно. Одна вещь выглядит разумной (x IS NULL) и (NOT x IS NULL) противоположны друг другу. Другое дело (тот факт, что ни «x IS NULL», ни «x IS NOT NULL» не верны), выглядит странно.
Тем не менее, это то, что что должно произойти документации PostgreSQL :
Должен признаться, я не думаю, что когда-либо использовал строковое сравнение с нулем, но я предполагаю, что, если такая возможность есть, может быть какой-то вариант ее использования. Во всяком случае, я не думаю, что это обычное дело.
источник