sql >> Database >  >> RDS >> Sqlserver

SQL Server 2008 MERGE-instructie - hoe de INSTEAD OF INSERT-trigger uit te schakelen om de MERGE . toe te staan

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
;



  1. Exporteer MySQL-database met PHP

  2. Moet ik EAV-waarden in een datatypetabel plaatsen?

  3. PostgreSQL-protocolfout. Sessie-instelling mislukt.. fout

  4. Volgorde als standaardwaarde voor een kolom