Als Teil einer MERGE
Abfrage, die ich ausführen möchte, möchte ich zur Laufzeit bestätigen, dass eine bestimmte Bedingung erfüllt ist. Wenn ein MERGE
Match gefunden wird, möchte ich eine bestimmte Spalte aktualisieren und die folgende Logik ausführen lassen:
- Wenn die Zielspalte lautet
NULL
, schreiben Sie den Quellwert - Wenn das Ziel ist
NOT NULL
, behaupten Sie, dass Ziel und Quelle identisch sind
Ich erwarte, dass die beiden Werte in Fall 2 immer identisch sind, aber ich habe möglicherweise einen Fehler gemacht (habe einen Fehler). In diesem Fall möchte ich die Anweisung zum Absturz bringen und meine App den Fehler melden lassen. Dies ist eine sehr seltene Fehlerbedingung, die im Rahmen der normalen Verarbeitung nicht auftreten kann.
Also dachte ich, ich könnte eine Division durch Null missbrauchen , um einen Absturz auszulösen:
MERGE
...
WHEN MATCHED BY TARGET THEN UPDATE SET
TargetCol = CASE
WHEN TargetCol IS NULL THEN SourceCol
WHEN TargetCol = SourceCol THEN SourceCol
ELSE 0/0 END --crash!
Funktioniert das zuverlässig? Gibt es einen Grund, warum dies nicht getan werden sollte?
RAISEERROR
könnte eine gute Wahl sein, wenn Sie innerhalb einer Abfrage behaupten möchten.CHECK
die ZieltabelleOUTPUT
einzuschränken? Das sollte die Aussage in die Luft jagen.Antworten:
Die Antwort darauf hängt von der Stärke der Garantie ab, die Sie benötigen. In der Vergangenheit gab es Fehler in der
CASE
Bewertungsreihenfolge, z. B. das konstante Falten eines fehlererzeugenden Ausdrucks . Es gibt keine aktuellen Fehler in SQL Server 2014, von denen ich weiß, dass sie sich auf Ihre Abfrage auswirken würden. Dies bedeutet jedoch nicht, dass sie möglicherweise in Zukunft nicht mehr auftreten.Dies ist natürlich ein Risiko für jeden Code, aber meiner Einschätzung nach ist das Risiko höher, wenn diese Technik mit kombiniert wird
MERGE
. Merge hat eine komplexe Implementierung, und wie Sie wissen , gab es in der Vergangenheit viele verwandte Fehler .Persönlich würde ich versuchen, eine Division durch Null als Teil der Lösung zu vermeiden. Eine bessere Option könnte sein, zu versuchen, einen Wert zu schreiben, der eine explizite
CHECK
(oder eine andere) Einschränkung für die Zieltabelle verletzt . Dies würde zu einem expliziten Assert-Operator im Ausführungsplan führen, der nach dem Merge-Operator positioniert ist. Es ist möglicherweise nicht wünschenswert , eine solche Einschränkung hinzuzufügen (oder sogar möglich, wenn die Spalte alle Werte in ihrer Typdomäne enthalten darf), aber es ist eine zu berücksichtigende Sache.Ein weiterer allgemeiner Vorschlag: Vermeiden Sie die Aktualisierung der Zielspalte, wenn die Werte übereinstimmen. Dies ist logischerweise ein No-Op, aber das wird nicht immer physisch übersetzt.
quelle