Podczas uruchamiania instrukcji aktualizacji, takiej jak ta poniżej, pojawia się komunikat o błędzie
Funkcje okienkowe mogą pojawiać się tylko w klauzulach SELECT lub ORDER BY.
UPDATE dbo.Dim_Chart_of_Account
SET Account_Order = LAG([Account_Order]) OVER (ORDER BY [Account_SKey])
Wiem, że można to łatwo obejść za pomocą aktualizowalnego pliku, jak poniżej
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
Moje pytanie brzmi: czy są jakieś powody, dla których nie jest to dozwolone w instrukcji aktualizacji, czy powinienem unikać używania cte z możliwością aktualizacji jako obejścia?
Obawiam się, że podczas używania funkcji okna z instrukcjami aktualizacji występują problemy i dlatego chciałbym zrozumieć, czy jest to dopuszczalna metoda, czy należy jej unikać.
sql-server
sql-server-2014
Neil P.
źródło
źródło
Odpowiedzi:
Funkcje okien nie są dozwolone w instrukcjach UPDATE, ponieważ UPDATE nie jest kompatybilny z SELECT lub ORDER BY.
Funkcje okna są podobne do instrukcji SELECT o zasięgu, które ponownie sprawdzają odpowiednie wiersze i stosują warunki, takie jak PARTITION BY i ORDER BY. Ponadto wiele funkcji okna wymaga klauzuli ORDER BY (na przykład ROW_NUMBER, LAG i FIRST_VALUE).
Instrukcje UPDATE używają SET zamiast SELECT, więc SELECT nie jest dozwolony nigdzie na tym samym poziomie zapytania. Każdy WYBÓR pojawiający się z UPDATE musi być zawarty w podzapytaniu.
Wyłączenie ORDER BY ma sens, biorąc pod uwagę, że instrukcja UPDATE jest obojętna względem kolejności, w jakiej aktualizuje wiersze.
Nie ma nieodłącznej wady używania CTE lub innego podzapytania jako obejścia, aby uzyskać UPDATE do użycia funkcji okna. Jest to powszechna praktyka zalecana przez ekspertów T-SQL, takich jak Itzik Ben-Gan. (Patrz strona 29 jego książki, Microsoft SQL Server 2012 Wysokowydajny T-SQL przy użyciu funkcji okna, w których opisuje ten dokładnie scenariusz.)
źródło