Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Изявление MERGE на SQL Server 2008 - как да деактивирате тригера INSTEAD OF INSERT, за да разрешите MERGE

Оптимизаторът на заявки прави статичен анализ на вашия T-SQL пакет и веднага щом види израза MERGE, ще потвърди изискванията. НЯМА да вземе предвид никакви DDL изрази, които засягат тригерите преди оператора MERGE.

Можете да заобиколите това, като използвате GO, за да разделите изразите на отделни партиди, но ако е в един SP (без GO изрази), имате два избора

  • поставете MERGE в поддържащ SP, който главният извиква; или
  • използване на динамичен SQL

Динамичен SQL

Нека създадем таблица с тригер

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

След това опитайте да се СЛИЕТЕ на масата

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
;

Не е добре...

Затова използваме динамичен 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
;

Процедура за поддръжка

Нека създадем процедура, която ще извърши MERGE (производствена процедура вероятно ще има променлива на таблица, ще използва #temp таблица или ще приеме някои параметри)

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

Не върви...

Дори за да го създадете, трябва да деактивирате тригерите - така че деактивирайте тригера и създайте отново процедурата - този път ще работи.

Накрая можете да стартирате тази партида, която работи

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Не може да се създаде екземпляр на доставчик на OLE DB Microsoft.Jet.OLEDB.4.0 за свързан сървър null

  2. Как да зададете първичен ключ при свързване с CreateTableDef

  3. WinRT System.Data - Свързване към SQL

  4. Възможно ли е окончателно да се определи дали дадена DML команда е била издадена от съхранена процедура?

  5. Вземете подниз в SQL Server