Documenti FirebirdGuida sull'uso di NULL nel linguaggio SQL di Firebird → Lavorare con i NULL
Firebird home Firebird home Indietro: Assegnare NULL ad un campo o ad una variabilePartenza: Documenti FirebirdRisali: Guida sull'uso di NULL nel linguaggio SQL di FirebirdAvanti: Sommario

Lavorare con i NULL

Testare un NULL - quando è necessario
Determinare se due campi sono identici
Modificare NULL con un valore

Questa sezione contiene alcuni suggerimenti pratici ed aesempi che possono essere utili nell'affrontare i NULL.

Testare un NULL - quando è necessario

Frequentemente non si ha bisogno di prendere misure particolari per i campi o le variabili che potrebbero essere NULL. Ad esempio, facendo come segue:

select * from Clienti where Citta = 'Verona'

molto probabilmente non si vogliono elencati i clienti per i quali la città non risulta specificata. Allo stesso modo:

if (Eta >= 18) then PotestVotare = 'Si'

non include le persone di età sconosciuta, quindi è difendibile, ed include le persone di età sconosciuta, ed è pure questo difendibile. Ma:

if (Eta >= 18) then PotestVotare = 'Si';
else PotestVotare = 'No';

sembra meno giustificabile: se non si conosce l'età di una persona, non si può esplicitamente negargli il diritto di voto. Ancora peggio, è far questo:

if (Eta < 18) then PotestVotare = 'No';
else PotestVotare = 'Si';

che non può avere lo stesso effetto del precedente esempio. Se alcuni di cui non si sa l'età sono in realtà minorenni (Eta < 18), gli si permette di votare!

Il miglior metodo in questo caso è controllare esplicitamente se vale NULL:

if (Eta is null) then PotestVotare = '??';
else 
  if (Eta >= 18) then PotestVotare = 'Si';
  else PotestVotare = 'No';

Nota

else si riferisce sempre al precedente if nello stesso blocco. Sarebbe sempre bene, ad ogni modo, evitare confusione mettendo un begin...end intorno al gruppo di linee. Qui non è stato fatto per limitare il numero di linee, ma chissà perchè ne ho aggiunte un bel po' per questa nota :-)

Determinare se due campi sono identici

Talvolta si deve determinare se due campi o due variabili sono uguali pure quando sono entrambi NULL. Per effettuare questo controllo in modo corretto si fa:

if (A = B or A is null and B is null) then...

oppure, esplicitando le precedenze degli operatori:

if ((A = B) or (A is null and B is null)) then...

È necessario avvertire di una cosa: se esattamente uno solo fra A e B è proprio NULL, l'espressione diventa NULL, non falsa! Questo è giusto, per quanto abbiamo visto prima, in uno statement di if, e si potrebbe anche aggiungere perfino un clausola else che può essere eseguita nel caso in cui A e B non sono uguali (incluso il caso in cui uno dei due è NULL e l'altro no):

if (A = B or A is null and B is null) 
  then ...cose da fare se A è uguale a B...
  else ...cose da fare se A è diverso da B...

Ma bisogna evitare come la peste la brillante idea di invertire le espressioni e di usarle come un test di ineguaglianza:

/* Da evitare! */
if (not(A = B or A is null and B is null))
  then ...cose da fare se A non è uguale a B...

Il codice qui sopra funziona correttamente se A e B sono entrambi NULL o entrambi diversi da NULL. Ma nel caso in cui uno solo dei due sia NULL non entra nella parte then perchè il test vale NULL, invece che essere valutato a vero come si potrebbe essere indotti erroneamente a pensare.

Volendo eseguire un codice se e solo se A e B sono differenti, si può usare una delle espressioni corrette viste sopra mettendo uno statement innocuo nella clausola then, oppure si può usare una espressione più lunga come questa:

/* Questo è un corretto test per diseguaglianza: */
if (A <> B
    or A is null and B is not null
    or A is not null and B is null) then...

Determinare se un campo è cambiato

Nei trigger è spesso utile sapere se un certo campo è stato modificato (compresa la trasformazione da NULL a non-NULL o viceversa) oppure è rimasto identico. Questo non è altro che un caso speciale del controllo di (dis)uguaglianza di due campi. Adesso si usa New.NomeCampo e Old.NomeCampo per A e B:

if (New.Valore = Old.Valore 
    or New.Valore is null and Old.Valore is null)
  then ...il campo Valore è rimasto uguale...
  else ...il campo Valore è cambiato...

Modificare NULL con un valore

La funzione COALESCE

In Firebird 1.5 c'è una funzione che è in grado di convertire NULL a quasi qualsiasi altra cosa. Questo permette di fare una conversione al volo e di usare il risultato per ulteriori elaborazioni, senza l'uso del costrutto “if (Espressione is null) then”. Questa particolare funzione è la COALESCE e si usa in questo modo:

COALESCE(Expr1, Expr2, Expr3, ...)

COALESCE riporta il primo valore non nullo (diverso da NULL) delle espressioni nella lista degli argomenti. Se tutte le espressioni sono NULL, la COALESCE riporta NULL.

Questo è il modo in cui per esempio si può usare COALESCE per ricostruire il nome completo di una persona a partire da nome, cognome e titolo, assumendo che talvolta il titolo possa essere NULL:

select coalesce ( Titolo || ' ', '' )
       || Cognome 
       || ' ' || Nome
from Persone

Oppure, per creare un nominativo il più informale possibile a partire da una tabella che contenga anche i soprannomi, e assumendo che possano essere NULL sia i soprannomi che i nomi:

select coalesce (Soprannome, Nome, 'Sig./Sig.ra')
       || ' ' || Cognome
from AltrePersone

COALESCE può venire in aiuto solo in quelle situazioni in cui il valore NULL può essere gestito allo stesso modo degli altri valori permessi per il tipo di dato. Se NULL necessità di una gestione particolare, come nel caso dell'esempio "può votare" visto precedentemente, l'unica opzione è usare la “if (Espressione is null) then”.

Firebird 1.0: le funzioni *NVL

In Firebird 1.0 non c'è la funzione COALESCE. Tuttavia si possono usare quattro funzioni UDF che permettono una buona parte della sua funzionalità. Queste UDF risiedono nella libreria fbudf e sono precisamente:

  • iNVL, per argomenti interi

  • i64NVL, per argomenti bigint

  • dNVL, per argomenti in duplice precisione

  • sNVL, per le stringhe

Le funzioni *NVL hanno esattamente due argomenti. Come COALESCE, riportano il primo argomento se non è NULL; altrimenti, riportano il secondo. Notare che in Firebird 1.0 la libreria fbudf e pertanto le funzioni *NVL sono solo disponibili in ambiente Windows.

Indietro: Assegnare NULL ad un campo o ad una variabilePartenza: Documenti FirebirdRisali: Guida sull'uso di NULL nel linguaggio SQL di FirebirdAvanti: Sommario
Documenti FirebirdGuida sull'uso di NULL nel linguaggio SQL di Firebird → Lavorare con i NULL