Come concatenare Stringhe in SQL Server (con esempi)

Se c’è un’operazione che ogni sviluppatore SQL compie centinaia di volte al giorno, è la concatenazione di stringhe. Che tu debba unire nome e cognome, costruire un indirizzo completo da vari campi o generare un messaggio di log, prima o poi ti imbatti nella necessità di mettere insieme pezzi di testo. Sembra banale, vero? Ebbene, in SQL Server ci sono diversi modi per farlo, e ognuno ha le sue piccole (grandi) peculiarità. Ignorarle? Un errore che ti costa tempo e mal di testa.

Prepariamoci a fare chiarezza e a capire quando usare cosa, evitando le trappole più comuni, specialmente quelle legate ai valori NULL!

1. L’Operatore +(…ma occhio ai NULL!)

Questo è il metodo più antico e forse il più istintivo. È lì da sempre, semplice da usare, e per unire due stringhe al volo fa il suo sporco lavoro.


SELECT 'Hello' + ' ' + 'World' AS Messaggio;
-- Risultato: Hello World

La Trappola dei NULL: Ed è qui che arriva il bello (o il brutto). L’operatore + ha un comportamento che devi stamparti in testa: se uno qualsiasi degli operandi concatenati è NULL, l’intero risultato della concatenazione sarà NULL. Punto.

Vediamo l’esempio più classico:


SELECT 'Nome:' + 'Mario' + ' Cognome:' + NULL AS DatiUtente;
-- Risultato: NULL

SELECT 'Articolo: ' + 'Libro' + ' - Autore: ' + NULL + ' - Prezzo: ' + '19.99' AS DettaglioProdotto;
-- Risultato: NULL (Perché "Autore" era NULL, ha rovinato tutto!)

Questa è la causa numero uno di query che restituiscono NULL inaspettati quando ti aspetti una stringa parziale. Devi gestirli esplicitamente con ISNULL() o COALESCE() se vuoi usare il +.

2. La Funzione CONCAT(): L’Amico dei NULL (Finalmente!)

Introdotta con SQL Server 2012, la funzione CONCAT() è stata una manna dal cielo proprio per la gestione dei NULL. Finalmente, un modo per concatenare senza che un singolo NULL ti mandasse a monte tutta la stringa!

La sua “killer feature” è che CONCAT() tratta i NULL come stringhe vuote (''). Quindi, puoi passargli N argomenti, e se alcuni sono NULL, semplicemente li ignorerà (o meglio, li tratterà come stringhe vuote) e continuerà la concatenazione con gli altri valori.


SELECT CONCAT('Hello', ' ', 'World') AS Messaggio;
-- Risultato: Hello World

SELECT CONCAT('Nome:', 'Mario', ' Cognome:', NULL) AS DatiUtente;
-- Risultato: Nome:Mario Cognome:

SELECT CONCAT('Articolo: ', 'Libro', ' - Autore: ', NULL, ' - Prezzo: ', '19.99') AS DettaglioProdotto;
-- Risultato: Articolo: Libro - Autore:  - Prezzo: 19.99 (Molto meglio!)

Quando usarla? Praticamente sempre quando non hai bisogno di un separatore fisso tra tutti gli elementi e vuoi la pace dei sensi con i NULL. È pulita, leggibile e meno propensa a errori.

3. La Funzione CONCAT_WS(): Con Separatore e Senza Problemi (dal 2017)

Per le vere gioie dello sviluppatore, in SQL Server 2017 è arrivata CONCAT_WS(). “WS” sta per “With Separator”, e il nome dice tutto. Questa funzione ti permette di specificare un separatore che verrà inserito tra ogni stringa che stai concatenando.

La sintassi è: CONCAT_WS(separatore, stringa1, stringa2, ...)

E la cosa migliore? Anche CONCAT_WS() è intelligente con i NULL: li ignora completamente! Non li trasforma in stringhe vuote come CONCAT(), semplicemente non li considera per la concatenazione, né per aggiungere il separatore.


SELECT CONCAT_WS('-', 'Rossi', 'Mario', 'Via Roma', '10', 'Roma', '00100') AS IndirizzoCompleto;
-- Risultato: Rossi-Mario-Via Roma-10-Roma-00100

SELECT CONCAT_WS(', ', 'Rossi', 'Mario', NULL, 'Roma', NULL, '00100') AS DatiUtenteConVirgola;
-- Risultato: Rossi, Mario, Roma, 00100 (Il NULL è stato ignorato, nessun doppio separatore!)

Quando usarla? Ogni volta che devi costruire una stringa complessa da più campi e vuoi che un determinato separatore sia presente tra ogni pezzo, ma solo se quel pezzo esiste. Perfetta per indirizzi, liste di tag, nomi composti da più parti, ecc.

Esempi Pratici: Metti le Mani in Pasta!

Per capire davvero le differenze, non c’è niente di meglio che sporcarsi le mani. Esegui questi script nel tuo SQL Server Management Studio (SSMS) o Azure Data Studio. Useremo una semplice tabella temporanea per simulare un po’ di dati.

Setup per i Test:


-- Pulisco la tabella temporanea se esiste già
IF OBJECT_ID('tempdb..#TestStrings') IS NOT NULL DROP TABLE #TestStrings;

-- Creo una tabella temporanea con un po' di dati di esempio
CREATE TABLE #TestStrings (
    ID INT IDENTITY(1,1) PRIMARY KEY,
    FirstName NVARCHAR(50),
    LastName NVARCHAR(50),
    MiddleName NVARCHAR(50), -- Questo avrà dei NULL
    City NVARCHAR(50),
    ZipCode NVARCHAR(10)
);

-- Inserisco i dati
INSERT INTO #TestStrings (FirstName, LastName, MiddleName, City, ZipCode) VALUES
('Mario', 'Rossi', NULL, 'Roma', '00100'),
('Luigi', 'Verdi', 'Carlo', 'Milano', '20100'),
('Anna', 'Bianchi', NULL, 'Napoli', NULL), -- Qui anche il CAP è NULL
('Giuseppe', 'Neri', 'Maria', NULL, '50100'); -- Qui la città è NULL

Test dell’Operatore +:


SELECT
    ID,
    FirstName,
    MiddleName,
    LastName,
    'Nome Completo (+)        : ' + FirstName + ' ' + MiddleName + ' ' + LastName AS FullNamePlus,
    'Indirizzo (+)            : ' + City + ', ' + ZipCode AS FullAddressPlus
FROM #TestStrings;

Cosa noterai: Molti NULL nei risultati finali, anche se solo una parte della stringa è NULL. Il record di Anna avrà NULL per l’indirizzo a causa del ZipCode a NULL, e il record di Mario e Anna avranno NULL nel nome completo a causa di MiddleName a NULL.

Test della Funzione CONCAT():


SELECT
    ID,
    FirstName,
    MiddleName,
    LastName,
    'Nome Completo (CONCAT)   : ' + CONCAT(FirstName, ' ', MiddleName, ' ', LastName) AS FullNameConcat,
    'Indirizzo (CONCAT)       : ' + CONCAT(City, ', ', ZipCode) AS FullAddressConcat
FROM #TestStrings;

Cosa noterai: I NULL ora sono stringhe vuote. Mario e Anna avranno un doppio spazio nel nome completo ('Mario Rossi') a causa del MiddleName NULL e dello spazio esplicito. Anna avrà 'Napoli, ' per l’indirizzo. Giuseppe avrà ', 50100' per l’indirizzo.

Test della Funzione CONCAT_WS():


SELECT
    ID,
    FirstName,
    MiddleName,
    LastName,
    'Nome Completo (CONCAT_WS): ' + CONCAT_WS(' ', FirstName, MiddleName, LastName) AS FullNameConcatWS,
    'Indirizzo (CONCAT_WS)    : ' + CONCAT_WS(', ', City, ZipCode) AS FullAddressConcatWS
FROM #TestStrings;

Cosa noterai: Questo è il più elegante. Il separatore viene applicato solo tra i valori *non-NULL*. Mario e Anna avranno un singolo spazio nel nome completo. Anna avrà `Napoli` e Giuseppe avrà `50100` per l’indirizzo, senza virgole o spazi aggiuntivi dove il campo era `NULL`.

Pulizia:


-- Non dimenticarti di pulire la tabella temporanea!
DROP TABLE #TestStrings;

Quale Usare? Il Consiglio del Programmatore!

  • + Operatore: Usalo solo se sei assolutamente certo che nessuna delle stringhe coinvolte sarà mai NULL, o se gestisci i NULL esplicitamente con ISNULL() o COALESCE(). È più conciso per due stringhe semplici. Personalmente, lo evito quasi sempre a meno che non stia facendo una concatenazione banale e controllata.
  • CONCAT(): La tua scelta predefinita quando devi unire più stringhe e non vuoi che un NULL in mezzo ti rovini tutto. La sua gestione dei NULL è robusta. Tieni a mente che aggiungerà uno spazio se lo metti tu come separatore e un elemento è NULL.
  • CONCAT_WS(): Il re della concatenazione strutturata. Se devi unire una serie di campi con un separatore consistente (es. nome, cognome, città, via) e vuoi che i campi NULL vengano semplicemente ignorati senza lasciare separatori “appesi”, questa è la funzione che fa per te. È la più “intelligente” con i NULL e produce output puliti.

Spero che questa carrellata ti abbia chiarito le idee. La prossima volta che concateni una stringa in SQL Server, pensa ai NULL e scegli lo strumento giusto per il lavoro. Ti risparmierai un sacco di debugging notturno!

Tag: sql server concat string