首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 觸發器完整教學:分類、魔術表、級聯、INSTEAD OF、實戰範例

     編輯:關於SqlServer

觸發器分類

類型觸發時機適用對象說明
AFTER (FOR)INSERT/UPDATE/DELETE 完成後資料表可多個,順序可用 sp_settriggerorder 設定
INSTEAD OF取代原動作執行資料表、檢視表每表每動作僅一個,常用於檢視表可更新化

兩張魔術表

  • inserted:新增/修改後的資料映像(UPDATE 視為刪舊增新,兩表皆有資料)。
  • deleted:刪除/修改前的資料映像。
  • 皆為記憶體常駐、唯讀、結構與基表一致,觸發器結束自動銷毀。

魔術表關係圖

實戰範例庫

1. AFTER INSERT:同步新增關聯資料

CREATE TRIGGER tgr_classes_insert ON classes FOR INSERT
AS
DECLARE @id INT, @name VARCHAR(20);
SELECT @id = id, @name = name FROM inserted;
INSERT INTO student (name, age, class_id) VALUES (@name + CAST(@id AS VARCHAR), 18+@id, @id);
PRINT '學生同步新增成功';

2. AFTER DELETE:刪除前備份

CREATE TRIGGER tgr_classes_delete ON classes FOR DELETE
AS
IF OBJECT_ID('classesBackup','U') IS NOT NULL
    INSERT INTO classesBackup SELECT name, createDate FROM deleted;
ELSE
    SELECT * INTO classesBackup FROM deleted;
PRINT '備份完成';

3. AFTER UPDATE:級聯修改關聯表

CREATE TRIGGER tgr_classes_update ON classes FOR UPDATE
AS
DECLARE @old VARCHAR(20), @new VARCHAR(20);
SELECT @old = name FROM deleted;
IF EXISTS (SELECT * FROM student WHERE name LIKE '%'+@old+'%')
BEGIN
    SELECT @new = name FROM inserted;
    UPDATE student SET name = REPLACE(name, @old, @new) WHERE name LIKE '%'+@old+'%';
    PRINT '級聯更新完成';
END

4. 欄位級 UPDATE 觸發:防改建立日期

CREATE TRIGGER tgr_classes_update_col ON classes FOR UPDATE
AS
IF UPDATE(createDate)
BEGIN
    RAISERROR('建立日期不可修改', 16, 1);
    ROLLBACK TRAN;
END

5. INSTEAD OF DELETE:自訂刪除邏輯(先刪子表再刪主表)

CREATE TRIGGER tgr_classes_insteadOf ON classes INSTEAD OF DELETE
AS
DECLARE @id INT, @name VARCHAR(20);
SELECT @id = id, @name = name FROM deleted;
DELETE student WHERE cid = @id;
DELETE classes WHERE id = @id;
PRINT '級聯刪除完成';

6. 通用稽核觸發器

CREATE TRIGGER tgr_student_log ON student AFTER INSERT, UPDATE, DELETE
AS
IF EXISTS(SELECT 1 FROM inserted) AND EXISTS(SELECT 1 FROM deleted)
    INSERT INTO log(action) VALUES('updated');
ELSE IF EXISTS(SELECT 1 FROM inserted)
    INSERT INTO log(action) VALUES('inserted');
ELSE
    INSERT INTO log(action) VALUES('deleted');

7. 資料驗證觸發器(年齡必須 ≥ 18)

CREATE TRIGGER tgr_valid_data ON student AFTER INSERT
AS
DECLARE @age INT; SELECT @age = age FROM inserted;
IF @age < 18 BEGIN RAISERROR('年齡不足',16,1); ROLLBACK TRAN; END

管理指令速查

-- 啟用/停用
ENABLE TRIGGER tgr_name ON table_name;
DISABLE TRIGGER tgr_name ON table_name;

-- 查看定義
EXEC sp_helptext 'tgr_name';
SELECT * FROM sys.triggers WHERE name = 'tgr_name';
SELECT * FROM sys.trigger_events WHERE object_id = OBJECT_ID('tgr_name');

效能與避坑提醒

  • 觸發器在同一交易內執行,邏輯複雜會拉長鎖定時間,影響並發。
  • 避免在觸發器發送郵件、呼叫 Web Service 等外部 I/O。
  • 大量批次操作(BULK INSERT、TRUNCATE)不啟動 觸發器。
  • 巢狀觸發器預設開啟(sp_configure 'nested triggers'),慎用避免無限遞迴。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved