PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

IS NOT NULL тестът за запис не връща TRUE, когато е зададена променлива

Виждам две възможни причини, защо ...

Нито едно от тези повишения не се появява в моя регистър на съобщенията

Не е регистриран

Първо, 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 - ако типът е добре познат тип ред. В противен случай имаме работа с анонимен запис и структурата е недефинирана и нямате достъп до елементи като начало. Но това не е така с 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;

Подробности в ръководството.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ядро на Entity Framework - Съдържа, чувствителен ли е главният или малък регистър?

  2. Нормализирайте индексите на масива за едномерен масив, така че да започват с 1

  3. Разделете данните в колоните, разделени със запетая, на допълнителни колони

  4. Буфери (кръг) в PostGIS

  5. Завръщането на XFS в Linux