sql >> Databasteknik >  >> RDS >> PostgreSQL

IS NOT NULL-testet för en post returnerar inte TRUE när variabeln är inställd

Jag ser två möjliga orsaker, varför ...

Ingen av dessa höjningar visas i min meddelandelogg

Inte loggat

För det första, en NOTICE skrivs normalt inte till databasloggen med standardinställningar. Jag citerar manualen här:

log_min_messages (enum )

Styr vilka meddelandenivåer som skrivs till serverloggen. Giltiga värden är DEBUG5 , DEBUG4 , DEBUG3 , DEBUG2 , DEBUG1 , INFO , NOTICE , WARNING , ERROR , LOG , FATAL och PANIC . (...)
Standardinställningen är VARNING . Observera att LOG har en annan rankning här än i client_min_messages .

Djärv betoning min. Notera också de olika standardinställningarna (NOTICE ) för client_min_messages (föregående punkt i manualen).

Ogiltigt test

För det andra, överväg hur ett raduttryck utvärderas. En test row_variable IS NULL returnerar TRUE if (och bara om) varje enskilt element är NULL . Med tanke på följande exempel:

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

Båda uttryck returnerar FALSE . Med andra ord, en rad (eller post) variabel (1, NULL) är varken NULL , och det är inte heller NOT NULL . Därför misslyckas båda dina test.

-> SQLfiddle med mer information.

Mer detaljer, förklaringar, länkar och en möjlig tillämpning för detta beteende i en CHECK begränsning i detta relaterade svar:
INTE NULL-begränsning över en uppsättning kolumner

Du kan till och med tilldela en postvariabel med NULL (rec := NULL ), vilket resulterar i att varje element är NULL - om typen är en välkänd radtyp. Annars har vi att göra med en anonym post och strukturen är odefinierad och du kan inte komma åt element till att börja med. Men det är inte fallet med en rowtype som i ditt exempel (som alltid är välkänt).

Lösning:FOUND

Vad är det korrekta sättet att testa om du fick en rad från en SELECT * INTO ?

Du måste tänka på att raden kan vara NULL, även om den tilldelades. Frågan kan mycket väl ha returnerat ett gäng NULL-värden (om tabelldefinitionen i din fråga tillåter NULL-värden). Ett sådant test skulle vara opålitligt genom designen.

Det finns ett enkelt och säkert tillvägagångssätt. Använd GET DIAGNOSTICS ... eller (i tillämpliga fall) den speciella variabeln 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. Hur får man PyPy, Django och PostgreSQL att fungera tillsammans?

  2. SQL Server:Filterutgång för sp_who2

  3. Adminer – Ett avancerat webbaserat databasadministrationsverktyg för Linux

  4. Hämta lista över alla noll- och inte-nollkolumner i SQL Server-databasen - SQL Server / T-SQL självstudie del 53