SQL Server: perché le funzioni della finestra non sono consentite nelle istruzioni di aggiornamento?


10

Quando eseguo una dichiarazione di aggiornamento, come quella qui sotto, viene visualizzato un errore che mi dice che

Le funzioni con finestra possono apparire solo nelle clausole SELECT o ORDER BY.

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

So che questo può essere facilmente risolto usando un cte aggiornabile, come di seguito

 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

La mia domanda è: ci sono dei motivi per cui ciò non è consentito in una dichiarazione di aggiornamento, dovrei evitare di usare un cte aggiornabile come soluzione alternativa?

La mia preoccupazione è che ci siano problemi quando si usano le funzioni della finestra con le istruzioni di aggiornamento e quindi vorrei capire se questo è un metodo accettabile o dovrebbe essere evitato.


1
Il CTE aggiornabile è accettabile e va bene. Non ho idea del perché non sia consentito nell'aggiornamento.
ypercubeᵀᴹ

2
Forse la protezione di Hallowe'en in qualche modo?
Aaron Bertrand

Risposte:


5

Le funzioni della finestra non sono consentite nelle istruzioni UPDATE perché UPDATE non è compatibile con SELECT o ORDER BY.

Le funzioni della finestra sono come le istruzioni SELECT con ambito che riesaminano le righe pertinenti e applicano condizioni come PARTITION BY e ORDER BY. Inoltre, molte funzioni della finestra richiedono una clausola ORDER BY (ROW_NUMBER, LAG e FIRST_VALUE, ad esempio).

Le istruzioni UPDATE utilizzano SET anziché SELECT, quindi SELECT non è consentito in nessun punto dello stesso livello di query. Qualsiasi SELECT che appare con UPDATE deve essere contenuto in una sottoquery.

Non consentire ORDER BY ha senso considerando che un'istruzione UPDATE è indifferente all'ordine in cui aggiorna le righe.

Non c'è alcun inconveniente intrinseco nell'uso di un CTE o di un'altra subquery come soluzione alternativa per ottenere un AGGIORNAMENTO per utilizzare una funzione di finestra. Questa è la pratica comune sostenuta da esperti di T-SQL come Itzik Ben-Gan. (Vedi pagina 29 del suo libro, T-SQL ad alte prestazioni di Microsoft SQL Server 2012 che utilizza le funzioni della finestra in cui copre questo scenario esatto.)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.