SQL Server-String-Verkettung mit Null

84

Ich erstelle eine berechnete Spalte über Felder, von denen einige möglicherweise null sind.

Das Problem ist, dass wenn eines dieser Felder null ist, die gesamte berechnete Spalte null ist. Ich verstehe aus der Microsoft-Dokumentation, dass dies erwartet wird und über die Einstellung SET CONCAT_NULL_YIELDS_NULL deaktiviert werden kann. Dort möchte ich dieses Standardverhalten jedoch nicht ändern, da ich die Auswirkungen auf andere Teile von SQL Server nicht kenne.

Gibt es eine Möglichkeit für mich, nur zu überprüfen, ob eine Spalte null ist, und ihren Inhalt nur dann an die berechnete Spaltenformel anzuhängen, wenn sie nicht null ist?

Alex
quelle
1
Die akzeptierte Antwort war zu dem Zeitpunkt richtig, als die Frage gestellt wurde, aber für alle unter SQL Server 2012 und höher (und dass diese Phase jeder sein sollte) @ Martin-Smiths Antwort ist die beste, da sie automatisch Nullen behandelt.
Dowlers

Antworten:

140

Sie können verwenden ISNULL(....)

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

Wenn der Wert der Spalte / des Ausdrucks tatsächlich NULL ist, wird stattdessen der zweite angegebene Wert (hier: leere Zeichenfolge) verwendet.

marc_s
quelle
22
"Coalesce" ist der Name der ANSI-Standardfunktion, ISNULL ist jedoch einfacher zu buchstabieren.
Philip Kelley
1
Und ISNULL scheint auch unter SQL Server ein bisschen schneller zu sein. Wenn Sie es also in einer Funktion verwenden möchten, die Zeichenfolgen zu einer berechneten Spalte verkettet, können Sie auf den ANSI-Standard verzichten und sich für Geschwindigkeit entscheiden (siehe Adam Machanic: sqlblog.com) / Blogs / adam_machanic / archive / 2006/07/12 /… )
marc_s
Ich habe gerade diese Isnull (,) - Abfrage verwendet, es hat viel geklappt, als ich Werte miteinander verkettet habe und wenn einer von ihnen null war, wurde auch alles null.
Sizons
Die Verwendung ISNULL()ist eine gute Lösung, aber ab SQL Server 2012 können Sie auch die CONCATFunktion verwenden, um das gleiche Ergebnis zu CONCAT(@Column1, @Column2)
erzielen
2
Es lohnt sich hier darauf hingewiesen , dass , wenn Sie tauschen wollen nullfür etwas anderes als eine leere Zeichenfolge, das heißt IsNull(@Column1, 'NULLVALUE'), mit IsNullder Ersatz String - Länge auf die Länge der Säule begrenzt wird es ersetzt, während es nicht mit istCoalesce
Jamie
55

Ab SQL Server 2012 ist dies alles mit der CONCATFunktion viel einfacher .

Es wird NULLals leere Zeichenfolge behandelt

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


SELECT CONCAT(@Column1,@Column2,@Column3); /*Returns FooBar*/
Martin Smith
quelle
Vielen Dank! Das war was ich brauchte !!
Shiva
Für ältere Versionen erhalten Sie "'CONCAT' ist kein anerkannter integrierter Funktionsname", verwenden Sie also COALESCE
Savage
3
@ Savage - COALESCE funktioniert nicht, weil es nicht verkettet, sondern nur das erste Argument ohne Null
zurückgibt
30

Verwende COALESCE . Anstelle von your_columnGebrauch COALESCE(your_column, ''). Dies gibt die leere Zeichenfolge anstelle von NULL zurück.

Mark Byers
quelle
OP will Strings zusammenfassen, COALESCE wird das nicht tun
codeulike
12

Verwenden

SET CONCAT_NULL_YIELDS_NULL  OFF 

Die Verkettung von Nullwerten mit einer Zeichenfolge führt nicht zu Null.

Bitte beachten Sie, dass dies eine veraltete Option ist. Vermeiden Sie die Verwendung. Weitere Informationen finden Sie in der Dokumentation .

Simran
quelle
11

Sie können auch CASE verwenden - mein Code unten prüft sowohl auf Nullwerte als auch auf leere Zeichenfolgen und fügt nur dann einen Trennzeichen hinzu, wenn ein folgender Wert vorhanden ist:

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 
Eddie
quelle
8

Ich wollte nur dazu beitragen, wenn jemand Hilfe beim Hinzufügen von Trennzeichen zwischen den Zeichenfolgen sucht, je nachdem, ob ein Feld NULL ist oder nicht.

Im Beispiel zum Erstellen einer einzeiligen Adresse aus separaten Feldern

Adresse1 , Adresse2 , Adresse3 , Stadt , Postleitzahl

In meinem Fall habe ich die folgende berechnete Spalte, die anscheinend so funktioniert, wie ich es möchte:

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

Hoffe das hilft jemandem!

ebooyens
quelle
Es gibt dort eine Menge redundanter verschachtelter Klammern, die entfernt werden könnten. Ein weiterer Tipp ist, dass Sie die case-Anweisung auch entfernen können, als ob address1 null ist. Der gesamte Ausdruck wird zu null ausgewertet (obwohl die case-Anweisung die Aufmerksamkeit auf sich zieht, dass dies passieren kann)
Alternator
7

ISNULL(ColumnName, '')

Ian Jacobs
quelle
1

Ich hatte auch große Probleme damit. Mit den obigen Fallbeispielen konnte es nicht funktionieren, aber das macht den Job für mich:

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

Ersetzen korrigiert die doppelten Leerzeichen, die durch die Verkettung einzelner Leerzeichen mit nichts dazwischen verursacht werden. r / ltrim entfernt alle Leerzeichen an den Enden.

BryDav
quelle
0

In SQL Server:

insert into Table_Name(PersonName,PersonEmail) values(NULL,'[email protected]')

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

Code dahinter:

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

insert into Table_Name(PersonName,PersonEmail) values(name,'"+email+"')
Srinivasula Reddy
quelle
0

Dieses Beispiel hilft Ihnen beim Umgang mit verschiedenen Typen beim Erstellen von Einfügeanweisungen

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'
Akmal Salikhov
quelle