Trình tối ưu hóa truy vấn thực hiện phân tích cú pháp tĩnh cho lô T-SQL của bạn và ngay khi thấy câu lệnh MERGE, nó sẽ xác thực các yêu cầu. Nó sẽ KHÔNG ảnh hưởng đến bất kỳ câu lệnh DDL nào ảnh hưởng đến trình kích hoạt trước câu lệnh MERGE.
Bạn có thể giải quyết vấn đề này bằng cách sử dụng GO để chia các câu lệnh thành các lô riêng biệt, nhưng nếu nó nằm trong một SP duy nhất (không có câu lệnh GO), bạn có hai lựa chọn
- đặt MERGE vào một SP hỗ trợ mà SP chính gọi; hoặc
- sử dụng SQL động
SQL động
Hãy tạo một bảng với trình kích hoạt
create table tg1(i int)
;
create trigger tg1_tg on tg1 instead of insert as
select 1
GO
Sau đó, cố gắng MERGE trên bàn
alter table tg1 disable trigger tg1_tg
;
merge tg1 as target
using (select 1 union all select 3) as source (X) on target.i = source.x
when matched then
delete
when not matched by target then
insert (i) values (x)
output $action, inserted.*, deleted.*
;
alter table tg1 enable trigger tg1_tg
;
Không tốt ..
Vì vậy, chúng tôi sử dụng SQL động
alter table tg1 disable trigger tg1_tg
;
exec ('
merge tg1 as target
using (select 1 union all select 3) as source (X) on target.i = source.x
when matched then
delete
when not matched by target then
insert (i) values (x)
output $action, inserted.*, deleted.*
;')
alter table tg1 enable trigger tg1_tg
;
Thủ tục hỗ trợ
Hãy tạo một thủ tục sẽ thực hiện MERGE (một chương trình sản xuất có thể sẽ có một biến bảng, sử dụng bảng #temp hoặc đưa vào một số tham số)
create proc tg1_MERGE as
merge tg1 as target
using (select 1 union all select 3) as source (X) on target.i = source.x
when matched then
delete
when not matched by target then
insert (i) values (x)
output $action, inserted.*, deleted.*
;
GO
Không đi ...
Ngay cả khi tạo nó, bạn cũng cần phải tắt trình kích hoạt - vì vậy hãy tắt trình kích hoạt và tạo lại chương trình - nó sẽ hoạt động vào khoảng thời gian này.
Cuối cùng, bạn có thể chạy lô này hoạt động
alter table tg1 disable trigger tg1_tg
;
exec tg1_MERGE
;
alter table tg1 enable trigger tg1_tg
;