it-swarm.com.de

Leere Ergebnismenge und Groß- / Kleinschreibung, wenn = 1

Ich bin mir ziemlich sicher, dass dies eine implizite Konvertierung ist, aber ich konnte keine Informationen darüber finden.

Angenommen, ich habe diese SQL:

SELECT
CASE WHEN (SELECT 1 WHERE (1=1)) = 1 THEN 1 ELSE 0 END

Meine Unterabfrage gibt eine Zeile zurück und wird daher mit 1 verglichen. Dies führt dazu, dass mein CASE WHEN die Ausgabe 1 erzeugt.

Selbst wenn ich die Unterabfrage so einstelle, dass keine Zeilen wie im folgenden Beispiel zurückgegeben werden, gibt die CASE-Anweisung das Ergebnis 0 zurück:

SELECT
CASE WHEN (SELECT 1 WHERE (1=0)) = 1 THEN 1 ELSE 0 END
  • Führt der SQL-Interpreter eine Konvertierung zwischen "leerer Menge" zu 0 oder 1 durch?
  • Ich fühle mich mit dieser Art von Vergleich nicht wohl. Meiner bescheidenen Meinung nach ist es besser, EXISTS wie folgt zu verwenden:

    SELECT
    CASE WHEN EXISTS(SELECT 1 WHERE (1=1)) THEN 1 ELSE 0 END
    

Gibt es Vor- oder Nachteile, wenn ich EXISTS nicht verwende?

2

Führt der SQL-Interpreter eine Konvertierung zwischen "leerer Menge" zu 0 oder 1 durch?

Nein, die Abfrage hat nicht 0 zurückgegeben, da das leere Ergebnis als 0 betrachtet wird, sondern weil die leere Ergebnismenge als NULL betrachtet wird und null nichts entspricht.

Wie du herausgefunden hast

SELECT
CASE WHEN (SELECT 1 WHERE (1=0)) = 1 THEN 1 ELSE 0 END

Gibt 0 zurück

Aber

SELECT
CASE WHEN (SELECT 1 WHERE (1=0)) = 0 THEN 1 ELSE 0 END

Gibt auch 0 zurück.

Die leere Ergebnismenge ist also nicht 1 und nicht 0, sondern NULL, wie durch belegt

SELECT
CASE WHEN (SELECT 1 WHERE (1=0)) is NULL THEN 1 ELSE 0 END

was 1 zurückgibt.

Siehe dies dbfiddle mit diesem Code.

NULL ist unbekannt, daher weiß SQL Server nicht, was es bedeutet.

Meiner bescheidenen Meinung nach ist es besser, EXISTS zu verwenden

Wenn Sie sich auf die Existenz einer Ergebnismenge verlassen, stimme ich zu, dass EXISTS wahrscheinlich der richtige Weg ist. Dafür ist die Konstruktion gemacht.
Wenn Sie 2 Werte außerhalb des Kurses vergleichen möchten, müssen Sie CASE verwenden, aber für Ihr angegebenes Szenario würde ich EXISTS verwenden

Ihr Vergleich wird unterbrochen, wenn Ihre Ergebnismenge mehr als eine Zeile oder Spalte enthält.

Zum Beispiel

SELECT
CASE WHEN (SELECT 1,2 WHERE (1=1)) = 1 THEN 1 ELSE 0 END

kehrt zurück

Nachricht 116 Ebene 16 Status 1 Zeile 2 In der Auswahlliste kann nur ein Ausdruck angegeben werden, wenn die Unterabfrage nicht mit EXISTS eingeführt wird.

und

SELECT
CASE WHEN (SELECT 1 WHERE (1=1) UNION SELECT 2 WHERE (1=1)) = 1 THEN 1 ELSE 0 END

kehrt zurück

Meldung 512 Ebene 16 Status 1 Zeile 1 Unterabfrage hat mehr als 1 Wert zurückgegeben. Dies ist nicht zulässig, wenn die Unterabfrage folgt = ,! =, <, <=,>,> = Oder wenn die Unterabfrage als Ausdruck verwendet wird.