sql >> Database teknologi >  >> RDS >> Sqlserver

SQL Server 2008 MERGE-sætning - hvordan man deaktiverer INSTEAD OF INSERT trigger for at tillade MERGE

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
;



  1. Now() uden tidszone

  2. Optimal Oracle SQL-forespørgsel til at fuldføre grupper efter på flere kolonner i en enkelt tabel indeholdende ~ 7.000.000 poster

  3. SQL Server 2008, forskellige WHERE-klausuler med én forespørgsel

  4. Sammenligning af datalagre for PostgreSQL - MVCC vs InnoDB