MERGE với OUTPUT dường như không làm đúng


8

Tôi đang thêm khóa ngoại vào bảng và xóa bất kỳ hàng nào vi phạm FK, sao chép chúng vào bảng ModifiedTable_invalid. Là một phần của tập lệnh, tôi đã nhận được lệnh MERGE sau:

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;

Tuy nhiên, lệnh này dường như đang chèn MỌI hàng từ ModifiedTable vào ModifiedTable_invalid, không chỉ những lệnh bị xóa bởi lệnh MERGE. Chuyện gì đang xảy ra và làm cách nào để tôi chỉ đặt các hàng đã xóa trong ModifiedTable_invalid?

Câu trả lời:


11

Khi bạn cập nhật một hàng, nó sẽ xuất hiện trong cả bảng giả inserted(giá trị sau cập nhật) và deleted(giá trị trước cập nhật). Nếu điều này có vẻ kỳ lạ, hãy xem xét rằng một bản cập nhật là một cách hợp lý việc xóa theo sau là một chèn (mặc dù bản cập nhật có thể không được thực hiện theo cách vật lý theo cách đó).

Khi được sử dụng với MERGE, OUTPUTmệnh đề có thể bao gồm một cột thêm có tên $action. Thêm cột này để truy vấn của bạn sẽ hiển thị mà hành động được thực hiện ( 'INSERT', 'UPDATE'hoặc 'DELETE') cho mỗi hàng.

Ví dụ:

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';

Hàng cập nhật sẽ có $action= 'UPDATE'.

Cũng xem bài đăng của Adam Machanic về việc sử dụng OUTPUT với câu lệnh MERGE cho một số ví dụ hay khác.


Hành vi này không có ý nghĩa với tôi. Tại sao các hàng chưa bị xóa xuất hiện trong DELETED.*?
thecoop

3
@thecoop - Nó cho phép bạn truy cập các giá trị "trước" và "sau" để cập nhật. Về mặt khái niệm, bạn có thể coi một bản cập nhật là một bản xóa theo sau là một bản chèn mặc dù đó thường không phải là cách nó thực sự xảy ra.
Martin Smith
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.