L'optimiseur de requête effectue une analyse statique de votre lot T-SQL et dès qu'il voit l'instruction MERGE, il valide les exigences. Il ne prendra PAS en compte les instructions DDL qui affectent les déclencheurs avant l'instruction MERGE.
Vous pouvez contourner ce problème en utilisant GO pour diviser les instructions en lots séparés, mais s'il s'agit d'un seul SP (pas d'instructions GO), vous avez deux choix
- mettre le MERGE dans un SP de support que le principal appelle ; ou
- utiliser SQL dynamique
SQL dynamique
Créons une table avec un déclencheur
create table tg1(i int)
;
create trigger tg1_tg on tg1 instead of insert as
select 1
GO
Essayez ensuite de FUSIONNER sur la table
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
;
Pas bon..
Nous utilisons donc du SQL dynamique
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
;
Procédure d'assistance
Créons une procédure qui effectuera la MERGE (une procédure de production aurait probablement une variable de table, utiliserait une table #temp ou prendrait certains paramètres)
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
N'y allez pas...
Même pour le créer, vous devez désactiver les déclencheurs - désactivez donc le déclencheur et créez à nouveau le proc - cela fonctionnera cette fois-ci.
Enfin, vous pouvez exécuter ce batch qui fonctionne
alter table tg1 disable trigger tg1_tg
;
exec tg1_MERGE
;
alter table tg1 enable trigger tg1_tg
;