MERGE dengan OUTPUT sepertinya tidak melakukan hal yang benar


8

Saya menambahkan kunci asing ke tabel, dan menghapus setiap baris yang melanggar FK, menyalinnya ke tabel ModifiedTable_invalid. Sebagai bagian dari skrip, saya mendapat perintah MERGE berikut:

MERGE ModifiedTable t1
USING TargetTable tt
ON t1.JoinColumn = tt.JoinColumn
WHEN MATCHED THEN
    UPDATE SET t1.FkColumn = tt.FkSource
WHEN NOT MATCHED BY SOURCE THEN DELETE
OUTPUT DELETED.* INTO ModifiedTable_invalid;

Namun, perintah ini tampaknya menyisipkan SETIAP baris dari ModifiedTable ke ModifiedTable_invalid, bukan hanya yang dihapus oleh perintah MERGE. Apa yang terjadi, dan bagaimana cara mendapatkannya agar hanya menempatkan baris yang dihapus di ModifiedTable_invalid?

Jawaban:


11

Ketika Anda memperbarui baris, itu akan muncul di tabel pseudo inserted( nilai post-update) dan deleted(pre-update value). Jika ini tampak aneh, pertimbangkan bahwa pembaruan secara logis adalah penghapusan diikuti oleh sisipan (meskipun pembaruan mungkin tidak dilakukan secara fisik seperti itu).

Ketika digunakan dengan MERGE, OUTPUTklausa dapat menyertakan kolom tambahan bernama $action. Menambahkan kolom ini untuk permintaan Anda akan menunjukkan yang tindakan yang diambil ( 'INSERT', 'UPDATE', atau 'DELETE') untuk setiap baris.

Sebagai contoh:

insert into ModifiedTable_invalid(Id /* And other columns */)
select
    Id
    /* And other columns */
from
(
    merge ModifiedTable t1
    using TargetTable t2 on t1.JoinColumn = t2.JoinColumn
    when matched then update set t1.FkColumn = t2.FkSource
    when not matched by source then delete
    output 
        $action as DMLAction,
        deleted.Id as Id /* And other columns... */
) outputs
where
    DMLAction = 'DELETE';

Baris yang diperbarui akan memiliki $action= 'UPDATE'.

Juga lihat posting Adam Machanic tentang menggunakan OUTPUT dengan pernyataan MERGE untuk beberapa contoh bagus lainnya.


Perilaku ini tidak masuk akal bagi saya. Mengapa baris yang belum dihapus muncul di DELETED.*?
thecoop

3
@thecoop - Memungkinkan Anda untuk mengakses nilai "sebelum" dan "setelah" untuk pembaruan. Secara konseptual, Anda mungkin menganggap pembaruan sebagai penghapusan yang diikuti oleh sisipan meskipun seringkali itu bukan bagaimana sebenarnya terjadi.
Martin Smith
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.