Seltsames Verhalten der CASE-Konstruktion

8

Hintergrund: Ich habe versucht, beim Erstellen von Dummy-Daten einige zufällige 'hex' -Werte zu erhalten und kam zu dieser Konstruktion:

%Vor%

Wenn ich dies auf meiner SQL Server 2008 R2-Instanz ausführe, bekomme ich eine Menge 'huh' Datensätze:

%Vor%

Ich verstehe wirklich nicht warum. Was ich erwarten würde, ist:

  • für jeden Datensatz NewID() enthält einen neuen zufälligen Wert
  • Binary_Checksum() berechnet basierend auf dem Wert
  • einen int
  • ABS() macht den Wert positiv
  • % 16 gibt den Rest dieses positiven Werts zurück, wenn er durch 16 geteilt würde, was dann ein Wert zwischen 0 und 15
  • wäre
  • Die CASE Konstruktion konvertiert den Wert in ein relevantes Zeichen
  • Da WHEN s für jeden Wert zwischen 0 und 15 vorhanden ist, sollte ELSE niemals benötigt werden

oder zumindest, das ist, was ich denke, sollte passieren ... aber offensichtlich läuft etwas schief auf der Straße ...

Wenn Sie dasselbe in einem zweistufigen Ansatz (via Temp-Tabelle) machen, sind die Huhs weg ...

%Vor%

Wer versteht das? Soweit ich das beurteilen kann, sollte es das gleiche Ergebnis geben (es ist tatsächlich kopierfähig), unabhängig davon, ob ich es direkt oder über einen Temp-Table mache ... Aber offensichtlich läuft etwas schief, wenn ich es in einer einzigen Aussage mache / p>

PS: Ich brauche dafür keine "Lösung", ich habe bereits einen Workaround (siehe unten), ich hoffe nur, dass mir jemand erklären kann, warum das funktioniert.

Workaround:

%Vor%     
deroby 15.12.2011, 09:48
quelle

2 Antworten

3

Ich glaube, dass es im Gegensatz zu der Beschreibung des einfachen CASE-Ausdrucks tatsächlich funktioniert wertet input_expression für jeden input_expression = when_expression -Vergleich neu auf (dies wäre normalerweise sicher, es sei denn, in diesem Fall gibt es eine nicht-deterministische Funktion in input_expression )

Was passiert ist also, dass es für jeden Vergleich immer wieder andere Zufallszahlen zwischen 0 und 15 erzeugt und die huh s herauskommen, wenn nach 16 Auswertungen / Vergleichen nie eine übereinstimmende Zahl generiert wurde.

Dies erzeugt nicht huh s:

%Vor%     
Damien_The_Unbeliever 15.12.2011, 09:54
quelle
8

Der Rechenskalar im Plan hat die folgende Formel

  

[Expr1038] = Skalarer Operator (CASE WHEN   abs (binary_checksum (newid ()))% (16) = (- 1) DANN 'Hallo' SONST FALL WENN   abs (binary_checksum (neuid ()))% (16) = (0) DANN '0' SONST FALL WENN   abs (binary_checksum (neuid ()))% (16) = (1) DANN '1' SONST FALL WENN   abs (binary_checksum (newid ()))% (16) = (2) DANN '2' SONST FALL WENN   abs (binary_checksum (newid ()))% (16) = (3) DANN '3' SONST FALL WENN   abs (binary_checksum (newid ()))% (16) = (4) DANN '4' SONDERFALL WENN   abs (binary_checksum (newid ()))% (16) = (5) DANN '5' SONST FALL WENN   abs (binary_checksum (neuid ()))% (16) = (6) DANN '6' SONDERFALL WENN   abs (binary_checksum (newid ()))% (16) = (7) DANN '7' SONDERFALL WENN   abs (binary_checksum (newid ()))% (16) = (8) DANN '8' SONDERFALL WENN   abs (binary_checksum (newid ()))% (16) = (9) DANN '9' SONDERFALL WANN   abs (binary_checksum (newid ()))% (16) = (10) DANN 'a' SONST FALL WENN   abs (binary_checksum (neuid ()))% (16) = (11) DANN 'b' SONST FALL WENN   abs (binary_checksum (neuid ()))% (16) = (12) DANN 'c' SONST FALL WENN   abs (binary_checksum (newid ()))% (16) = (13) DANN 'D' SONST FALL WENN   abs (binary_checksum (newid ()))% (16) = (14) DANN 'e' SONST FALL WENN   abs (binary_checksum (newid ()))% (16) = (15) DANN 'f' ELSE 'huh' ENDE ENDE   Ende Ende Ende Ende Ende Ende Ende Ende Ende Ende Ende Ende Ende)

Die Zufallszahl wird wiederholt neu ausgewertet, anstatt einmal ausgewertet und in jedem Zweig der CASE -Anweisung konstant gehalten zu werden.

Die (feste) vorgeschlagene Lösung in Damiens Antwort funktioniert für mich

%Vor%

Weil der Plan 2 Rechenoperatoren hat. Der erste mit der Definition

%Vor%

Dann wird dieser konstante Ausdruck Expr1038 in den Ausdruck CASE eingegeben. Ich bin mir nicht sicher, ob dieses Verhalten absolut garantiert ist. Es kann den Launen des Optimierers unterliegen.

    
Martin Smith 15.12.2011 09:54
quelle