SQL Server - Warum sind Fensterfunktionen in Update-Anweisungen nicht zulässig?

10

Wenn ich eine Update-Anweisung wie die folgende ausführe, wird eine Fehlermeldung angezeigt

Fensterfunktionen können nur in den Klauseln SELECT oder ORDER BY angezeigt werden.

UPDATE dbo.Dim_Chart_of_Account
SET Account_Order = LAG([Account_Order]) OVER (ORDER BY [Account_SKey])

Ich weiß, dass dies mit einem aktualisierbaren CTE wie unten leicht umgangen werden kann

 WITH my_cte AS (
     SELECT [Account_Order], LAG([Account_Order]) OVER (ORDER BY [Account_SKey]) AS acc_order_lag
     FROM Dim_Chart_of_Account
)
UPDATE my_cte
SET [Account_Order] = acc_order_lag

Meine Frage ist, gibt es Gründe, warum dies in einer Update-Anweisung nicht zulässig ist. Sollte ich vermeiden, ein aktualisierbares CTE als Problemumgehung zu verwenden?

Ich mache mir Sorgen, dass es Probleme bei der Verwendung von Fensterfunktionen mit Update-Anweisungen gibt, und daher möchte ich verstehen, ob dies eine akzeptable Methode ist oder vermieden werden sollte.

Neil P.
quelle
1
Der aktualisierbare CTE ist akzeptabel und in Ordnung. Keine Ahnung, warum es im UPDATE nicht erlaubt ist.
Ypercubeᵀᴹ
2
Vielleicht Halloween-Schutz?
Aaron Bertrand

Antworten:

5

Fensterfunktionen sind in UPDATE-Anweisungen nicht zulässig, da UPDATE nicht mit SELECT oder ORDER BY kompatibel ist.

Fensterfunktionen ähneln SELECT-Anweisungen mit Gültigkeitsbereich, die die relevanten Zeilen erneut untersuchen und Bedingungen wie PARTITION BY und ORDER BY anwenden. Darüber hinaus erfordern viele Fensterfunktionen eine ORDER BY-Klausel (z. B. ROW_NUMBER, LAG und FIRST_VALUE).

UPDATE-Anweisungen verwenden SET anstelle von SELECT, sodass SELECT nirgendwo auf derselben Abfrageebene zulässig ist. Jedes mit UPDATE erscheinende SELECT muss in einer Unterabfrage enthalten sein.

Das Deaktivieren von ORDER BY ist sinnvoll, da eine UPDATE-Anweisung der Reihenfolge, in der sie Zeilen aktualisiert, gleichgültig ist.

Die Verwendung eines CTE oder einer anderen Unterabfrage als Problemumgehung, um ein UPDATE zur Verwendung einer Fensterfunktion zu erhalten, hat keinen inhärenten Nachteil. Dies ist die gängige Praxis von T-SQL-Experten wie Itzik Ben-Gan. (Siehe Seite 29 seines Buches Microsoft SQL Server 2012 Hochleistungs-T-SQL mithilfe von Fensterfunktionen, in dem er genau dieses Szenario behandelt.)

Doug Lane
quelle