SQL Server: ¿por qué no se permiten las funciones de ventana en las declaraciones de actualización?

10

Cuando ejecuto una declaración de actualización, como la siguiente, aparece un error que me dice que

Las funciones en ventana solo pueden aparecer en las cláusulas SELECT u ORDER BY.

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

Sé que esto se puede solucionar fácilmente usando un cte actualizable, como a continuación

 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

Mi pregunta es: ¿hay alguna razón por la cual esto no está permitido en una declaración de actualización? ¿Debería evitar usar un cte actualizable como solución alternativa?

Mi preocupación es que hay problemas al usar funciones de ventana con declaraciones de actualización y, por lo tanto, me gustaría entender si este es un método aceptable o si debe evitarse.

Neil P
fuente
1
El CTE actualizable es aceptable y está bien. No tengo idea de por qué no está permitido en la ACTUALIZACIÓN.
ypercubeᵀᴹ
2
Tal vez la protección de Halloween de algún tipo?
Aaron Bertrand

Respuestas:

5

Las funciones de ventana no están permitidas en las instrucciones UPDATE porque UPDATE no es compatible con SELECT u ORDER BY.

Las funciones de ventana son como sentencias SELECT de ámbito que reexaminan las filas relevantes y aplican condiciones como PARTITION BY y ORDER BY. Además, muchas funciones de ventana requieren una cláusula ORDER BY (ROW_NUMBER, LAG y FIRST_VALUE, por ejemplo).

Las instrucciones UPDATE usan SET en lugar de SELECT, por lo que SELECT no está permitido en ningún lugar del mismo nivel de consulta. Cualquier SELECCIÓN que aparezca con ACTUALIZACIÓN debe estar contenido en una subconsulta.

No permitir ORDER BY tiene sentido teniendo en cuenta que una instrucción UPDATE es indiferente al orden en que actualiza las filas.

No existe una desventaja inherente al uso de un CTE u otra subconsulta como solución para obtener una ACTUALIZACIÓN para usar una función de ventana. Esa es la práctica común defendida por expertos de T-SQL como Itzik Ben-Gan. (Consulte la página 29 de su libro, Microsoft SQL Server 2012 High-Performance T-SQL Using Window Functions donde cubre este escenario exacto).

Doug Lane
fuente