Щоб вирішити вашу проблему, ми повинні застосувати програмний підхід до проблеми. Тут можна пройти два маршрути. Причина необхідності цих підходів полягає в тому, що ви не можете відключити тригер для конкретного оператора, його можна відключити лише для всієї таблиці.
Варіант 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_sesions
sys.sysпроцеси
Ідеологія тут полягає в тому, що бінарний рядок, який ви встановлюєте, піддається лише поточному сеансу, тож коли тригер виконується під час вашого сеансу, він побачить обсяг та змінні налаштування Context_info
функції, і він перейде до вхідної частини тригера замість цього.
Варіант 2: Таблиця темп
Іцзік Бен-Ган має чудове рішення у своїй книзі "Всередині Microsoft SQL Server 2008 Програмування T-SQL: Програмування T-SQL", яка також є у його пізнішій книзі T-SQL Querying . Основна проблема з цим над 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