Ich habe eine ähnliche T-SQL-Anweisung geschrieben (die ursprüngliche sieht anders aus, aber ich möchte hier ein einfaches Beispiel geben):
SELECT first_name +
CASE last_name WHEN null THEN 'Max' ELSE 'Peter' END AS Name
FROM dbo.person
Diese Anweisung enthält keine Syntaxfehler, aber die case-Klausel wählt immer den ELSE-Teil aus - auch wenn der Nachname null ist. Aber wieso?
Was ich tun möchte, ist, Vorname und Nachname zu vereinen, aber wenn Nachname null ist, wird der gesamte Name null:
SELECT first_name +
CASE last_name WHEN null THEN '' ELSE ' ' + last_name END AS Name
FROM dbo.person
Wissen Sie, wo das Problem liegt?
COALESCE
im Grunde intern übersetzt inCASE
. Das Problem mit CASE ist, dasslast_name
es zweimal evaluiert wird und zu anderen Nebenwirkungen führen kann - siehe diesen ausgezeichneten Artikel . Um das zu lösen, was gefragt wurde, würde ich lieber mit demISNULL(' '+ last_name, '')
im Kommentar unten erwähnten gehen .Der WHEN-Teil wird mit == verglichen, aber Sie können nicht wirklich mit NULL vergleichen. Versuchen
stattdessen oder COALESCE:
('' + Nachname ist NULL, wenn Nachname NULL ist, daher sollte in diesem Fall '' zurückgegeben werden)
quelle
Es gibt viele Lösungen, aber keine deckt ab, warum die ursprüngliche Aussage nicht funktioniert.
Nach dem Wann gibt es eine Überprüfung auf Gleichheit, die wahr oder falsch sein sollte.
Wenn einer oder beide Teile eines Vergleichs null sind, ist das Ergebnis des Vergleichs UNBEKANNT, was in einer Fallstruktur wie falsch behandelt wird. Siehe: https://www.xaprb.com/blog/2006/05/18/why-null-never-compares-false-to-anything-in-sql/
Um dies zu vermeiden, ist Coalesce der beste Weg.
quelle
Mit Ihrer Anfrage können Sie auch Folgendes tun:
quelle
ISNULL(' '+ last_name, '')
, um den redundanten Speicherplatz zu verhindern.Das Problem ist, dass null nicht als gleichwertig angesehen wird, daher stimmt die Klausel nie überein.
Sie müssen explizit auf null prüfen:
quelle
Versuchen:
Dies fügt das Leerzeichen zum Nachnamen hinzu. Wenn es null ist, wird das gesamte Leerzeichen + Nachname auf NULL gesetzt und Sie erhalten nur einen Vornamen, andernfalls erhalten Sie ein erstes + Leerzeichen + Nachname.
Dies funktioniert so lange, wie die Standardeinstellung für die Verkettung mit Nullzeichenfolgen festgelegt ist:
Dies sollte kein
OFF
Problem sein, da der Modus in zukünftigen Versionen von SQl Server nicht mehr verfügbar istquelle
Das Problem ist, dass NULL nicht als gleichwertig angesehen wird, auch nicht als sich selbst, aber der seltsame Teil ist, dass es auch nicht gleich sich selbst ist.
Berücksichtigen Sie die folgenden Anweisungen (die in SQL Server T-SQL übrigens illegal sind, in My-SQL jedoch gültig sind. Dies ist jedoch das, was ANSI für null definiert und auch in SQL Server mithilfe von case-Anweisungen usw. überprüft werden kann.)
SELECT NULL = NULL -- Results in NULL
SELECT NULL <> NULL -- Results in NULL
Es gibt also keine richtige / falsche Antwort auf die Frage, stattdessen ist die Antwort auch null.
Dies hat viele Auswirkungen, zum Beispiel in
WHEN NULL
Bedingung ).SELECT a + NULL -- Results in NULL
Sie können dieses Verhalten in SQL Server durch Angabe überschreiben. Dies
SET ANSI_NULLS OFF
wird jedoch NICHT empfohlen und sollte nicht durchgeführt werden, da dies viele Probleme verursachen kann, einfach aufgrund einer Abweichung vom Standard.(Als Randnotiz gibt es in My-SQL die Option, einen speziellen Operator
<=>
für den Nullvergleich zu verwenden.)Im Vergleich dazu wird in allgemeinen Programmiersprachen null als regulärer Wert behandelt und ist gleich sich selbst. Dies ist jedoch der NAN-Wert, der auch nicht gleich sich selbst ist, aber zumindest 'false' zurückgibt, wenn er mit sich selbst verglichen wird (und Wenn geprüft wird, ob verschiedene Programmiersprachen nicht gleich sind, haben sie unterschiedliche Implementierungen.
Beachten Sie jedoch, dass es in den Basissprachen (z. B. VB usw.) kein Schlüsselwort 'null' gibt und stattdessen das Schlüsselwort 'Nothing' verwendet wird, das nicht im direkten Vergleich verwendet werden kann. Stattdessen muss 'IS' wie in SQL verwendet werden. es ist jedoch in der Tat gleich sich selbst (wenn indirekte Vergleiche verwendet werden).
quelle
quelle
Wenn Sie frustriert sind, versuchen Sie Folgendes:
Versuchen Sie stattdessen dieses:
LEN(ISNULL(last_Name,''))
Misst die Anzahl der Zeichen in dieser Spalte, die Null ist, unabhängig davon, ob sie leer oder NULL ist. DaherWHEN 0 THEN
wird sie als wahr ausgewertet und das '' wie erwartet zurückgegeben.Ich hoffe das ist eine hilfreiche Alternative.
Ich habe diesen Testfall für SQL Server 2008 und höher aufgenommen:
quelle
Jason hat einen Fehler entdeckt, also funktioniert das ...
Kann jemand die anderen Plattformversionen bestätigen?
SQL Server:
MySQL:
Orakel:
quelle
Sie können die IsNull-Funktion verwenden
Wenn eine Spalte null ist, erhalten Sie ein leeres Zeichen
Kompatibel mit Microsoft SQL Server 2008+
quelle
Verwenden Sie die in SQL Server 2012 verfügbare CONCAT-Funktion.
quelle
Ich habe versucht, eine Saite zu gießen und auf eine Saite mit der Länge Null zu testen, und es hat funktioniert.
quelle
NULL ist nichts gleich. Die case-Anweisung sagt im Grunde, wenn der Wert = NULL ist, wird er niemals getroffen.
Es gibt auch mehrere gespeicherte Systemprozeduren, die mit Ihrer Syntax falsch geschrieben wurden. Siehe sp_addpullsubscription_agent und sp_who2.
Ich wünschte, ich könnte Microsoft über diese Fehler informieren, da ich die im System gespeicherten Prozesse nicht ändern kann.
quelle