Nástroj Query Optimizer provede statickou analýzu vaší dávky T-SQL a jakmile uvidí příkaz MERGE, ověří požadavky. NEBUDE zohledňovat žádné příkazy DDL, které ovlivňují spouštěče před příkazem MERGE.
Můžete to obejít pomocí GO k rozdělení příkazů do samostatných dávek, ale pokud je to v jediném SP (žádné příkazy GO), máte dvě možnosti
- umístit MERGE do podpůrného SP, který volá ten hlavní; nebo
- použijte dynamické SQL
Dynamické SQL
Vytvořme tabulku se spouštěčem
create table tg1(i int)
;
create trigger tg1_tg on tg1 instead of insert as
select 1
GO
Pak se pokuste MERGE na stole
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
;
Není dobré..
Použijeme tedy dynamické SQL
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
;
Postup podpory
Vytvořme proceduru, která provede MERGE (produkční proces by pravděpodobně měl proměnnou tabulky, použijte #temp tabulku nebo převezme nějaké parametry)
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
Nechoď...
I k jeho vytvoření je potřeba deaktivovat spouštěče – takže deaktivujte spouštěč a vytvořte znovu proces – tentokrát to bude fungovat.
Nakonec můžete spustit tuto dávku, která funguje
alter table tg1 disable trigger tg1_tg
;
exec tg1_MERGE
;
alter table tg1 enable trigger tg1_tg
;