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:
NewID()
enthält einen neuen zufälligen Wert Binary_Checksum()
berechnet basierend auf dem Wert 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 CASE
Konstruktion konvertiert den Wert in ein relevantes Zeichen 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% 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:
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.
Tags und Links sql-server sql-server-2008 tsql