sql >> Database teknologi >  >> RDS >> PostgreSQL

IS NOT NULL test for en post returnerer ikke TRUE, når variabel er indstillet

Jeg ser to mulige årsager, hvorfor ...

Ingen af ​​disse forhøjelser vises i min beskedlog

Ikke logget

For det første en NOTICE skrives normalt ikke til databaseloggen med standardindstillinger. Jeg citerer manualen her:

log_min_messages (enum )

Styrer hvilke meddelelsesniveauer der skrives til serverloggen. Gyldige værdier er DEBUG5 , DEBUG4 , DEBUG3 , DEBUG2 , DEBUG1 , INFO , NOTICE , WARNING , ERROR , LOG , FATAL og PANIC . (...)
Standarden er ADVARSEL . Bemærk at LOG har en anden rangering her end i client_min_messages .

Fed understregning min. Bemærk også den anden standard (NOTICE ) for client_min_messages (forrige punkt i manualen).

Ugyldig test

For det andet skal du overveje, hvordan et rækkeudtryk evalueres. En test row_variable IS NULL returnerer TRUE hvis (og kun hvis) hvert enkelt element er NULL . Givet følgende eksempel:

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

Begge udtryk returnerer FALSE . Med andre ord, en række (eller post) variabel (1, NULL) er hverken NULL , og det er heller ikke NOT NULL . Derfor mislykkes begge dine tests.

-> SQLfiddle med flere detaljer.

Flere detaljer, forklaring, links og en mulig anvendelse for denne adfærd i en CHECK begrænsning i dette relaterede svar:
IKKE NULL begrænsning over et sæt kolonner

Du kan endda tildele en postvariabel med NULL (rec := NULL ), hvilket resulterer i, at hvert element er NULL - hvis typen er en velkendt rækketype. Ellers har vi at gøre med en anonym post, og strukturen er udefineret, og du kan ikke få adgang til elementer til at begynde med. Men det er ikke tilfældet med en rowtype som i dit eksempel (som altid er velkendt).

Løsning:FOUND

Hvad er den korrekte måde at teste, om du har modtaget en række fra en SELECT * INTO ?

Du skal overveje, at rækken kunne være NULL, selvom den blev tildelt. Forespørgslen kunne meget vel have returneret en masse NULL-værdier (hvis tabeldefinitionen i din forespørgsel tillader NULL-værdier). En sådan test ville være upålidelig ved design.

Der er en enkel og sikker tilgang. Brug GET DIAGNOSTICS ... eller (hvor relevant) den specielle variabel 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;

Detaljer i manualen.




  1. Python-modulet cx_Oracle-modulet kunne ikke findes

  2. Upload dokumenter til Azure Data Lake og eksporter data ved hjælp af SSIS

  3. MySQL konverter timediff output til dag, time, minut, sekund format

  4. Hvordan forhindrer man BOB i at fortolke et spørgsmålstegn som en pladsholder?