Чтобы решить вашу проблему, мы должны принять программный подход к проблеме. Есть два маршрута, по которым вы можете пойти здесь. Причина, по которой эти подходы нужны, заключается в том, что вы не можете отключить триггер для определенного оператора, его можно отключить только для всей таблицы.
Вариант 1: Context_Info ()
У Самуэля Ванги на MS SQL Tips был отличный пример:
USE AdventureWorks;
GO
-- creating the table in AdventureWorks database
IF OBJECT_ID('dbo.Table1') IS NOT NULL
DROP TABLE dbo.Table1
GO
CREATE TABLE dbo.Table1(ID INT)
GO
-- Creating a trigger
CREATE TRIGGER TR_Test ON dbo.Table1 FOR INSERT,UPDATE,DELETE
AS
DECLARE @Cinfo VARBINARY(128)
SELECT @Cinfo = Context_Info()
IF @Cinfo = 0x55555
RETURN
PRINT 'Trigger Executed'
-- Actual code goes here
-- For simplicity, I did not include any code
GO
Теперь, когда Самуил не хочет, чтобы триггер выполнялся, они используют это:
SET Context_Info 0x55555
INSERT dbo.Table1 VALUES(100)
Context_Info
использует следующие системные представления для получения информации о текущем сеансе:
sys.dm_exec_requests
sys.dm_exec_sessions
sys.sysprocesses
Идеология здесь заключается в том, что двоичная строка, которую вы устанавливаете, доступна только для текущего сеанса, поэтому, когда триггер выполняется во время вашего сеанса, он увидит область действия и настройку переменной Context_info
функции и перейдет к escape-части триггера. вместо.
Вариант 2: временная таблица
У Ицик Бен-Гана есть отличное решение в его книге «Внутри Microsoft SQL Server 2008 Программирование на T-SQL: Программирование на T-SQL», а также в его более поздней книге « Запросы на T-SQL» . Основная проблема с этим по context_info
функции - незначительные издержки TempDB.
Чтобы испортить сюрприз, но не разрушить сюжет книг (я чувствовал, что их стоит покупать и читать), вы измените свой триггер.
Ваш триггер должен выполнить проверку для временной таблицы. Если временная таблица существует, триггер должен знать, что нужно завершить, а не выполнять действия.
В операторе обновления, который вы хотите выполнить, сначала создайте временную таблицу. Он будет отображаться в той же транзакции, что и триггер, и он будет игнорировать ваш оператор.
Пример триггера:
CREATE TRIGGER TRIGGERNAME ON TABLENAME for INSERT AS
IF OBJECT_ID('tempdb..#FAKETEMPTABLE') IS NOT NULL RETURN;
GO
Пример начального оператора, когда вы не хотите запускать триггер:
CREATE TABLE #FAKETEMPTABLE(col1 SMALLINT);
В целом это для вашего примера:
ALTER TRIGGER tiu_benefit ON benefit FOR
...
AS
...
IF OBJECT_ID('tempdb..#FAKETEMPTABLE') IS NOT NULL RETURN;
--... rest of code here
GO
CREATE TABLE #FAKETEMPTABLE(col1 SMALLINT);
UPDATE benefit SET editor = 'srh' where benefit_id = 9876;
GO