SQL Server - mengapa fungsi jendela tidak diizinkan dalam laporan pembaruan?

10

Saat menjalankan pernyataan pembaruan, seperti yang di bawah ini, saya mendapatkan kesalahan mengatakan itu

Fungsi Windowed hanya dapat muncul di klausa SELECT atau ORDER BY.

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

Saya tahu bahwa ini dapat dengan mudah dikerjakan menggunakan cte yang dapat diupdate, seperti di bawah ini

 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

Pertanyaan saya adalah, apakah ada alasan mengapa ini tidak diizinkan dalam pernyataan pembaruan, haruskah saya menghindari menggunakan cte yang dapat diupdate sebagai solusinya?

Kekhawatiran saya adalah bahwa ada masalah ketika menggunakan fungsi jendela dengan pernyataan pembaruan dan oleh karena itu saya ingin memahami apakah ini metode yang dapat diterima atau harus dihindari.

Neil P
sumber
1
CTE yang dapat diperbarui dapat diterima dan baik-baik saja. Tidak tahu mengapa itu tidak diizinkan di UPDATE.
ypercubeᵀᴹ
2
Mungkin Hallowe'en semacam perlindungan?
Aaron Bertrand

Jawaban:

5

Fungsi jendela tidak diizinkan dalam pernyataan UPDATE karena UPDATE tidak kompatibel dengan SELECT atau ORDER BY.

Fungsi jendela seperti pernyataan SELECT yang dicakup yang memeriksa ulang baris yang relevan dan menerapkan kondisi seperti PARTITION BY dan ORDER BY. Selain itu, banyak fungsi jendela memerlukan klausa ORDER BY (ROW_NUMBER, LAG, dan FIRST_VALUE, misalnya).

Pernyataan UPDATE menggunakan SET dan bukannya SELECT, jadi SELECT tidak diizinkan di mana pun di tingkat permintaan yang sama. SELECT apa pun yang muncul dengan UPDATE harus dimuat dalam subquery.

Menolak ORDER BY masuk akal mengingat pernyataan UPDATE tidak mempedulikan urutan pembaruannya.

Tidak ada kelemahan bawaan untuk menggunakan CTE atau subquery lainnya sebagai solusi untuk mendapatkan UPDATE untuk menggunakan fungsi jendela. Itulah praktik umum yang dianjurkan oleh para ahli T-SQL seperti Itzik Ben-Gan. (Lihat halaman 29 dari bukunya, Microsoft SQL Server 2012 T-SQL Kinerja Tinggi Menggunakan Fungsi Jendela di mana ia membahas skenario yang tepat ini.)

Doug Lane
sumber