PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Test IS NOT NULL dla rekordu nie zwraca TRUE, gdy zmienna jest ustawiona

Widzę dwa możliwe powody, dlaczego...

Żadna z tych podwyżek nie pojawia się w moim dzienniku wiadomości

Nie zalogowany

Po pierwsze, NOTICE nie jest zwykle zapisywany w dzienniku bazy danych z ustawieniami domyślnymi. Cytuję instrukcję tutaj:

log_min_messages (enum )

Kontroluje, które poziomy komunikatów są zapisywane w dzienniku serwera. Prawidłowe wartości to DEBUG5 , DEBUG4 , DEBUG3 , DEBUG2 , DEBUG1 , INFO , NOTICE , WARNING , ERROR , LOG , FATAL i PANIC . (...)
Domyślnie OSTRZEŻENIE . Zauważ, że LOG ma tu inną pozycję niż w client_min_messages .

Moje odważne podkreślenie. Zwróć także uwagę na inną wartość domyślną (NOTICE ) dla client_min_messages (poprzednia pozycja w instrukcji).

Nieprawidłowy test

Po drugie, zastanów się, jak jest oceniane wyrażenie wiersza. Testowa row_variable IS NULL zwraca TRUE jeśli (i tylko jeśli) każdy element jest NULL . Biorąc pod uwagę następujący przykład:

SELECT (1, NULL) IS NULL AS a     -- FALSE
      ,(1, NULL) IS NOT NULL AS b -- also FALSE

Oba wyrażenia zwracają FALSE . Innymi słowy, zmienna wiersza (lub rekordu) (1, NULL) nie ma wartości NULL , ani nie jest NOT NULL . Dlatego oba testy nie powiodły się.

-> SQLfiddle więcej szczegółów.

Więcej szczegółów, wyjaśnień, linków i możliwe zastosowanie tego zachowania w CHECK ograniczenie w tej powiązanej odpowiedzi:
Ograniczenie NOT NULL na zbiorze kolumn

Możesz nawet przypisać zmienną rekordu o wartości NULL (rec := NULL ), co powoduje, że każdy element ma wartość NULL - jeśli typ jest dobrze znanym typem wiersza. W przeciwnym razie mamy do czynienia z anonimowym rekordem, którego struktura jest niezdefiniowana i nie można uzyskać dostępu do elementów na początku. Ale tak nie jest w przypadku rowtype jak w twoim przykładzie (który jest zawsze dobrze znany).

Rozwiązanie:FOUND

Jaki jest poprawny sposób sprawdzenia, czy otrzymałeś wiersz z SELECT * INTO? ?

Musisz wziąć pod uwagę, że wiersz może mieć wartość NULL, nawet jeśli został przypisany. Zapytanie mogło równie dobrze zwrócić kilka wartości NULL (jeśli definicja tabeli w zapytaniu zezwala na wartości NULL). Taki test byłby z założenia niewiarygodny.

Istnieje proste i bezpieczne podejście. Użyj GET DIAGNOSTICS ... lub (jeśli dotyczy) specjalną zmienną 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;

Szczegóły w instrukcji.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak zmienić styl daty w PostgreSQL?

  2. Postgres NIE w tablicy

  3. Jak pobrać kolumnę Postgres bytea jako plik?

  4. Jak przekonwertować epokę Uniksa na znacznik czasu?

  5. Dodaj godziny do wartości czasu w PostgreSQL