Ответ 1
Я вижу две возможные причины, почему...
Ни один из этих повышений не отображается в журнале сообщений
Не зарегистрировано
Во-первых, NOTICE
обычно не записывается в журнал базы данных с настройками по умолчанию. Я цитирую руководство здесь:
log_min_messages
(enum
)Управляет, какие уровни сообщений записываются в журнал сервера. Допустимые значения:
DEBUG5
,DEBUG4
,DEBUG3
,DEBUG2
,DEBUG1
,INFO
,NOTICE
,WARNING
,ERROR
,LOG
,FATAL
иPANIC
. (...)
Значение по умолчанию ПРЕДУПРЕЖДЕНИЕ. Заметим, чтоLOG
здесь имеет другой ранг, чем вclient_min_messages
.
Смелый акцент мой. Также обратите внимание на разное значение по умолчанию (NOTICE
) для client_min_messages
(предыдущий элемент в руководстве).
Неверный тест
Во-вторых, рассмотрим, как оценивается выражение строки. Тест row_variable IS NULL
возвращает TRUE
, если (и только если) каждый отдельный элемент NULL
. В следующем примере:
SELECT (1, NULL) IS NULL AS a -- FALSE
,(1, NULL) IS NOT NULL AS b -- also FALSE
Оба выражения возвращают FALSE
. Другими словами, переменная строки (или записи) (1, NULL)
не является ни NULL
, ни ее NOT NULL
. Поэтому оба ваших теста не работают.
- > SQLfiddle с более подробной информацией.
Дополнительные сведения, объяснения, ссылки и возможное приложение для этого поведения в ограничении CHECK
в этом связанном ответе:
NOT NULL ограничение по набору столбцов
Вы даже можете назначить переменную записи с NULL (rec := NULL
), что приводит к тому, что каждый элемент имеет значение NULL - если тип является известным типом строки. В противном случае мы имеем дело с анонимной записью, а структура undefined, и вы не можете получить доступ к элементам для начала. Но это не тот случай с rowtype
, как в вашем примере (который всегда хорошо известен).
Решение: FOUND
Какой правильный способ проверить, получили ли вы строку из
SELECT * INTO
?
Вы должны учитывать, что строка может быть NULL, даже если она была назначена. Запрос мог бы очень хорошо вернуть кучу значений NULL (если определение таблицы в вашем запросе допускает значения NULL). Такой тест будет ненадежным по дизайну.
Существует простой и безопасный подход. Используйте GET DIAGNOSTICS ...
или (если применимо) специальную переменную FOUND
:
SELECT * FROM my_table WHERE owner_id = 6 INTO my_var;
IF NOT FOUND THEN
RAISE NOTICE 'Query did not return a row!';
END IF;