sql >> Databasteknik >  >> RDS >> Sqlserver

SQL Server 2008 MERGE-sats - hur man inaktiverar INSTEAD OF INSERT-utlösaren för att tillåta MERGE

Query Optimizer gör en statisk analys av din T-SQL-batch, och så snart den ser MERGE-satsen kommer den att validera kraven. Det tar INTE hänsyn till några DDL-satser som påverkar utlösare före MERGE-satsen.

Du kan kringgå detta genom att använda GO för att dela upp satserna i separata partier, men om det är i en enda SP (inga GO-satser) har du två val

  • lägg MERGE i en support SP som den huvudsakliga anropar; eller
  • använd dynamisk SQL

Dynamisk SQL

Låt oss skapa en tabell med en trigger

create table tg1(i int)
;
create trigger tg1_tg on tg1 instead of insert as 
select 1
GO

Försök sedan att SLÅ ihop 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
;

Inte bra...

Så vi använder 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
;

Supportprocedur

Låt oss skapa en procedur som kommer att utföra MERGE (en produktionsproc skulle förmodligen ha en tabellvariabel, använda en #temp-tabell eller ta in några parametrar)

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

No go...

Till och med för att skapa den måste du inaktivera triggers - så inaktivera triggern och skapa processen igen - det kommer att fungera den här gången.

Slutligen kan du köra denna batch som fungerar

alter table tg1 disable trigger tg1_tg
;
exec tg1_MERGE
;
alter table tg1 enable trigger tg1_tg
;



  1. Vertikalt skalande PostgreSQL

  2. Deltar i Streak MySQL Query

  3. MySQL främmande nycklar på mig själv

  4. Oracle - ingen funktion med namn X finns i detta omfång