Để giải quyết vấn đề của bạn, chúng tôi phải thực hiện một cách tiếp cận theo chương trình cho vấn đề. Có hai tuyến đường bạn có thể đi đến đây. Lý do cần các cách tiếp cận này là vì bạn không thể vô hiệu hóa trình kích hoạt cho một câu lệnh cụ thể, nó chỉ có thể bị vô hiệu hóa trong toàn bộ bảng.
Tùy chọn 1: Context_Info ()
Samuel Vanga trên MS SQL Tips đã có một ví dụ tuyệt vời:
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
Bây giờ khi Samuel không muốn kích hoạt thực thi, họ sử dụng điều này:
SET Context_Info 0x55555
INSERT dbo.Table1 VALUES(100)
Context_Info
sử dụng các chế độ xem hệ thống sau để lấy thông tin về phiên hiện tại:
sys.dm_exec numquests
sys.dm_exec_simes
sys.sys Processes
Hệ tư tưởng ở đây là chuỗi nhị phân bạn đang đặt chỉ được hiển thị cho phiên hiện tại, do đó, khi trình kích hoạt thực thi trong phiên của bạn, nó sẽ thấy phạm vi và cài đặt biến của Context_info
hàm và nó sẽ nhảy đến phần thoát của trình kích hoạt thay thế.
Tùy chọn 2: Bảng Temp
Itzik Ben-Gan có một giải pháp tuyệt vời trong cuốn sách "Bên trong Microsoft SQL Server 2008 Lập trình T-SQL: Lập trình T-SQL" cũng nằm trong cuốn sách sau này của ông T-SQL Querying . Vấn đề chính với context_info
chức năng này là chi phí nhỏ trên TempDB.
Để làm hỏng sự ngạc nhiên nhưng không phá hỏng cốt truyện của những cuốn sách (tôi cảm thấy chúng đáng để mua và đọc), bạn sẽ thay đổi kích hoạt của mình.
Kích hoạt của bạn nên thực hiện kiểm tra cho một bảng tạm thời. Nếu bảng tạm thời tồn tại, kích hoạt nên biết để kết thúc và không thực hiện các hành động.
Trong câu lệnh cập nhật bạn muốn thực hiện, trước tiên hãy tạo bảng tạm thời. Nó sẽ được nhìn thấy trong cùng một giao dịch với trình kích hoạt và nó sẽ khiến trình kích hoạt bỏ qua tuyên bố của bạn.
Ví dụ về kích hoạt:
CREATE TRIGGER TRIGGERNAME ON TABLENAME for INSERT AS
IF OBJECT_ID('tempdb..#FAKETEMPTABLE') IS NOT NULL RETURN;
GO
Ví dụ về câu lệnh bắt đầu khi bạn không muốn kích hoạt chạy:
CREATE TABLE #FAKETEMPTABLE(col1 SMALLINT);
Đặt nó hoàn toàn cho ví dụ của bạn:
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