NULL

Il valore NULL esiste nel modello relazionale come il databse Oracle.
  • NULL non è paragonabile a nessun altro valore atomico
  • NULL non è paragonabile a NULL
  • NULL non supporta l'operatore di test di uguaglianza '='
  • NULL è verificabile in modo predicibile solo con l'operatori 'IS' o come insieme derivato da precedenti operazioni di proiezione e selezione.
Insomma, il NULL è comodo per esprimere un concetto fondamentale dell'algebra relazionale, ma è più difficile da gestire quando sono coinvolte operatori cosiddetti "di gruppo".

Che succede ad esempio con la funzione MAX(), che valuta un set di valori e ritorna il più "alto"?
Facciamo il caso di questa tabella: T1 ( C1 number, C2 varchar2(10) )

Se la tabella è vuota l'istruzione "select max (c1) from t1" ritorna una riga in cui la singola pseudo colonna max(c1) contiene il valore NULL.
SQL> select max (c1) from t1;

   MAX(C1)
----------


Se la tabella è vuota l'istruzione "select max (c1) from t1 group by c1", apparentemente equivalente alla precedente, non ritorna righe. 
SQL> select max (c1) from t1 group by c1;

no rows selected

Questo dipende dal fatto che il qualificatore group by forza l'applicazione di una "selezione" prima dell'eventuale ordinamento e raggruppamento dei valori presupposto della determinazione del valore massimo. 
E' come se ci fosse una where nascosta. 
La where viene eseguita prima delle funzioni di select (sql va letto dal basso verso l'alto da un punto di vista del piano di esecuzione), quindi non trovando righe la funzione max non viene applicata perché l'esito della where implicita nella group by è "no rows selected" (cioè insieme vuoto).

E' chiaro quindi che, a seconda di quali sono i dati nelle tabelle delle query innestate e di come la query è scritta, perché alcuni operatori supportano o meno il null, la query possa andare in errore in un caso e non nell'altro.

In generale l'output delle funzioni di gruppo vanno testate con la funzione NVL. 
Scrivendo ad esempio 

SQL> select nvl(max (c1),0) from t1 group by c1;

no rows selected

Qui ho la certezza che la query non resituisce righe,

SQL> select nvl (max (c1), 0) from t1;

NVL(MAX(C1),0)
--------------
             0

Questa invece ho certezza che la query mi restituisce il NULL.

Post popolari in questo blog

ORA-12154: TNS: il listener non è attualmente a conoscenza del servizio richiesto nel descrittore di connessione

Create e Drop Pluggable Database