Query Optimizer laver en statisk parse af din T-SQL-batch, og så snart den ser MERGE-sætningen, vil den validere kravene. Det vil IKKE tage højde for nogen DDL-sætninger, der påvirker triggerne før MERGE-sætningen.
Du kan omgå dette ved at bruge GO til at opdele sætningerne i separate batches, men hvis det er i en enkelt SP (ingen GO-sætninger), har du to valgmuligheder
- sæt MERGE i en support-SP, som den primære kalder; eller
- brug dynamisk SQL
Dynamisk SQL
Lad os oprette en tabel med en trigger
create table tg1(i int)
;
create trigger tg1_tg on tg1 instead of insert as
select 1
GO
Forsøg derefter at FLERE på bordet
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
;
Ikke godt..
Så vi bruger dynamisk 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
;
Supportprocedure
Lad os oprette en procedure, der vil udføre FLÉNING (en produktionsproces ville sandsynligvis have en tabelvariabel, bruge en #temp-tabel eller tage nogle parametre ind)
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
Nej gå...
Selv for at oprette det, skal du deaktivere triggerne - så deaktiver triggeren og opret processen igen - det vil virke denne gang.
Endelig kan du køre denne batch, som virker
alter table tg1 disable trigger tg1_tg
;
exec tg1_MERGE
;
alter table tg1 enable trigger tg1_tg
;