Concatenazione di stringhe di SQL Server con Null


85

Sto creando una colonna calcolata tra i campi di cui alcuni sono potenzialmente nulli.

Il problema è che se uno qualsiasi di questi campi è nullo, l'intera colonna calcolata sarà nullo. Capisco dalla documentazione Microsoft che questo è previsto e può essere disattivato tramite l'impostazione SET CONCAT_NULL_YIELDS_NULL. Tuttavia, non voglio modificare questo comportamento predefinito perché non conosco le sue implicazioni su altre parti di SQL Server.

C'è un modo per me di controllare se una colonna è nulla e solo aggiungere il suo contenuto all'interno della formula della colonna calcolata se non è nulla?


2
La risposta accettata era giusta al momento in cui è stata posta la domanda, ma per tutti su SQL Server 2012 e versioni successive (e questa fase dovrebbe essere per tutti) La risposta di @ Martin-Smiths è la migliore in quanto gestisce automaticamente i valori nulli.
Dowlers

Risposte:


142

Puoi usare ISNULL(....)

SET @Concatenated = ISNULL(@Column1, '') + ISNULL(@Column2, '')

Se il valore della colonna / espressione è effettivamente NULL, verrà invece utilizzato il secondo valore specificato (qui: stringa vuota).


22
"Coalesce" è il nome della funzione standard ANSI, ma ISNULL è più facile da scrivere.
Philip Kelley

1
E ISNULL sembra essere un po 'più veloce anche su SQL Server, quindi se vuoi usarlo in una funzione che concatena le stringhe in una colonna calcolata, potresti rinunciare allo standard ANSI e optare per la velocità (vedi Adam Machanic: sqlblog.com / blogs / adam_machanic / archive / 2006/07/12 /… )
marc_s

Ho appena usato questa query Isnull (,), ha funzionato molto perché stavo concatenando i valori insieme e se uno di essi era nullo, anche tutto diventava nullo.
Sizons

L'uso ISNULL()è una buona soluzione, ma da SQL Server 2012 in poi, puoi anche usare la CONCATfunzione per ottenere lo stesso risultato:CONCAT(@Column1, @Column2)
Muhammad Musavi

2
Vale la pena notare qui che se vuoi scambiare nullcon qualcosa di diverso da una stringa vuota, cioè IsNull(@Column1, 'NULLVALUE'), con IsNullla lunghezza della stringa di sostituzione è limitata alla lunghezza della colonna che sta sostituendo, mentre non è conCoalesce
Jamie

58

Da SQL Server 2012 è tutto molto più semplice con la CONCATfunzione.

Viene considerata NULLcome una stringa vuota

DECLARE @Column1 VARCHAR(50) = 'Foo',
        @Column2 VARCHAR(50) = NULL,
        @Column3 VARCHAR(50) = 'Bar';


SELECT CONCAT(@Column1,@Column2,@Column3); /*Returns FooBar*/

Grazie! Questo era ciò di cui avevo bisogno !!
Shiva

Per le versioni precedenti ottieni "'CONCAT' non è un nome di funzione integrato riconosciuto", quindi usa COALESCE
Savage

3
@ Savage - COALESCE non funzionerà perché non concatena, restituisce solo il primo argomento non nullo
codeulike

30

Usa COALESCE . Invece di your_columnusare COALESCE(your_column, ''). Ciò restituirà la stringa vuota invece di NULL.


OP vuole concatenare le stringhe insieme, COALESCE non lo farà
codeulike

12

Uso

SET CONCAT_NULL_YIELDS_NULL  OFF 

e la concatenazione di valori null in una stringa non risulterà in null.

Tieni presente che questa è un'opzione deprecata, evita di utilizzare. Vedere la documentazione per maggiori dettagli.


11

Puoi anche usare CASE: il mio codice sotto controlla sia i valori nulli che le stringhe vuote e aggiunge un separatore solo se c'è un valore da seguire:

SELECT OrganisationName, 
'Address' = 
CASE WHEN Addr1 IS NULL OR Addr1 = '' THEN '' ELSE Addr1 END + 
CASE WHEN Addr2 IS NULL OR Addr2 = '' THEN '' ELSE ', ' + Addr2 END + 
CASE WHEN Addr3 IS NULL OR Addr3 = '' THEN '' ELSE ', ' + Addr3 END + 
CASE WHEN County IS NULL OR County = '' THEN '' ELSE ', ' + County END 
FROM Organisations 

8

Volevo solo contribuire a questo se qualcuno cerca aiuto con l'aggiunta di separatori tra le stringhe, a seconda che un campo sia NULL o meno.

Quindi nell'esempio della creazione di un indirizzo di una riga da campi separati

Indirizzo1 , Indirizzo2 , Indirizzo3 , Città , PostCode

nel mio caso, ho la seguente colonna calcolata che sembra funzionare come voglio:

case 
    when [Address1] IS NOT NULL 
    then (((          [Address1]      + 
          isnull(', '+[Address2],'')) +
          isnull(', '+[Address3],'')) +
          isnull(', '+[City]    ,'')) +
          isnull(', '+[PostCode],'')  
end

Spero che aiuti qualcuno!


C'è un bel po 'di bracketing nidificato ridondante che potrebbe essere rimosso. Un altro suggerimento è che potresti anche rimuovere l'istruzione case come se address1 fosse nullo l'intera espressione restituirà null (anche se l'istruzione case attira l'attenzione che ciò può accadere)
Alternatore


1

Ho avuto molti problemi anche con questo. Non sono riuscito a farlo funzionare utilizzando gli esempi di casi sopra, ma questo fa il lavoro per me:

Replace(rtrim(ltrim(ISNULL(Flat_no, '') + 
' ' + ISNULL(House_no, '') + 
' ' + ISNULL(Street, '') + 
' ' + ISNULL(Town, '') + 
' ' + ISNULL(City, ''))),'  ',' ')

Sostituisci corregge i doppi spazi causati dalla concatenazione di singoli spazi senza nulla tra di loro. r / ltrim elimina gli spazi alle estremità.


0

In Sql Server:

insert into Table_Name(PersonName,PersonEmail) values(NULL,'xyz@xyz.com')

PersonName is varchar(50), NULL is not a string, because we are not passing with in single codes, so it treat as NULL.

Codice dietro:

string name = (txtName.Text=="")? NULL : "'"+ txtName.Text +"'";
string email = txtEmail.Text;

insert into Table_Name(PersonName,PersonEmail) values(name,'"+email+"')

0

Questo esempio ti aiuterà a gestire vari tipi durante la creazione di istruzioni di inserimento

select 
'insert into doc(Id, CDate, Str, Code, Price, Tag )' + 
'values(' +
      '''' + convert(nvarchar(50), Id) + ''',' -- uniqueidentifier
    + '''' + LEFT(CONVERT(VARCHAR, CDate, 120), 10) + ''',' -- date
    + '''' + Str+ ''',' -- string
    + '''' + convert(nvarchar(50), Code)  + ''',' -- int
    + convert(nvarchar(50), Price) + ',' -- decimal
    + '''' + ISNULL(Tag, '''''') + '''' + ')'  -- nullable string

 from doc
 where CDate> '2019-01-01 00:00:00.000'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.