De Query Optimizer voert een statische analyse uit van uw T-SQL-batch en zodra deze de MERGE-instructie ziet, worden de vereisten gevalideerd. Er wordt GEEN rekening gehouden met DDL-instructies die van invloed zijn op de triggers vóór de MERGE-instructie.
Je kunt dit omzeilen door GO te gebruiken om de statements in afzonderlijke batches te splitsen, maar als het in een enkele SP staat (geen GO-statements), heb je twee keuzes
- zet de MERGE in een ondersteunings-SP die de hoofd-SP aanroept; of
- gebruik dynamische SQL
Dynamische SQL
Laten we een tabel maken met een trigger
create table tg1(i int)
;
create trigger tg1_tg on tg1 instead of insert as
select 1
GO
Probeer dan samen te voegen op de tafel
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
;
Niet goed..
We gebruiken dus dynamische 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
;
Ondersteuningsprocedure
Laten we een procedure maken die de MERGE uitvoert (een productieproc zou waarschijnlijk een tabelvariabele hebben, een #temp-tabel gebruiken of enkele parameters opnemen)
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
Niet gaan...
Zelfs om het te maken, moet je de triggers uitschakelen - dus schakel de trigger uit en maak de proc opnieuw - het zal deze keer werken.
Eindelijk kunt u deze batch uitvoeren die werkt
alter table tg1 disable trigger tg1_tg
;
exec tg1_MERGE
;
alter table tg1 enable trigger tg1_tg
;