Errori frequenti con l’SQL: quali sono e come evitarli

Il linguaggio SQL ha un paradigma dichiarativo e una radice “english-like”. Di conseguenza risulta generalmente più facilmente comprensibile di molti altri linguaggi di programmazione. Anche la relativa curva di apprendimento è il più delle volte più ripida. Tuttavia, se non correttamente studiato, anch’esso presenta svariati trabocchetti che possono indurre anche il programmatore più esperto in errore. Riportiamo qui degli esempi di errori che fanno riferimento al dialetto T-SQL sul database Microsoft Sql Server.

La funzione IsNull tronca le stringhe

Provate a eseguire questo frammento di codice sul vostro database Sql Server:

DECLARE @x AS VARCHAR(1) = NULL; 
DECLARE @y AS VARCHAR(4) = 'test';
SELECT ISNULL(@x, @y);

Probabilmente qualcuno di voi resterà come me stupito dal fatto che la query restituisce la sola lettera “t”, invece che l’intera stringa test. Infatti, l’output della funzione IsNull avrà come tipo quello del primo argomento, nel nostro esempio varchar(1). Di conseguenza la stringa test sarà convertita implicitamente in t.

Bisogna porre particolare attenzione al caso in cui il secondo argomento abbia un valore che non è convertibile nel tipo del primo argomento. Il codice seguente produrrà ad esempio un errore

DECLARE @x AS INT = NULL; 
DECLARE @y AS VARCHAR(4)= 'test';
SELECT ISNULL(@x, @y);

Ecco una delle possibili cause quando sentite un vostro collega esclamare

“la procedura che ha sempre funzionato stanotte è fallita”

Particolarmente importante è notare che in presenza della funzione coalesce il comportamento è diverso che segue le regole di precedenza dei tipi riportate in questo articolo https://learn.microsoft.com/it-it/sql/t-sql/data-types/data-type-precedence-transact-sql?view=sql-server-ver16

Errori SQL: aggiornare più colonne con una sola update

Se abituati a lavorare con altri linguaggi di programmazione, si potrebbe pensare che dopo questa query

UPDATE tabella
SET    col1 = 1,
       col2 = col1;

la colonna col2 sarà valorizzata con il valore 1 in tutti i record. Al contrario, gli aggiornamenti all’interno di una update non hanno un “ordine cronologico”. Col2 sarà aggiornata con il relativo valore originale di col1, riga per riga.

Ovviamente è diverso il caso in cui scrivo due update separate:

UPDATE tabella
SET    col1 = 1;
UPDATE tabella
SET    col2 = col1;

In questo caso entrambe le colonne saranno valorizzate interamente con 1.

Una CROSS JOIN può causare un output vuoto

Molto spesso la CROSS JOIN è utilizzata quando abbiamo l’esigenza di ripetere  lo stesso identico valore su tutte le righe di una tabella. Dietro questa scelta possono esserci svariate motivazioni, ad esempio una richiesta esplicita dell’utente finale inerente la presentazione dei dati in un report, o per agevolare query di trasformazione successive. Ma cosa succede se la query utilizzata per costruire questo valore non restituisce risultati?

Se Tabella1 ha dieci record, mentre Tabella2 ha zero record la seguente query

SELECT *
FROM   Tabella1
CROSS JOIN Tabella2;

restituirà zero righe. Magari il voler aggiungere una semplice colonna di supporto contenente delle informazioni marginali, potrebbe provocare un errore ben più grave: l’intero output diventerà vuoto.

Per evitare che questo accada possiamo sostituire la CROSS JOIN con una LEFT JOIN in questo modo

SELECT *
FROM   Tabella1
LEFT JOIN Tabella2
  ON 1=1;

o, in modo forse più elegante, possiamo sostituire la cross join con l’outer apply

SELECT *
FROM   Tabella1
OUTER APPLY Tabella2;

Se vuoi approfondire l’utilizzo di cross apply e outer apply puoi leggere questo mio articolo di approfondimento.

Continua a imparare

Torna in alto
Torna su