INSERT/UPDATE/DELETE → AFTER (預設) / INSTEAD OFCREATE/ALTER/DROP 等結構變更 (SQL 2005+)inserted:新增/修改後的資料deleted:刪除/修改前的資料ROLLBACK 撤銷觸發操作。CREATE TRIGGER trigger_name
ON table_or_view_name
[WITH ENCRYPTION]
{FOR | AFTER | INSTEAD OF} {[INSERT] [,] [UPDATE] [,] [DELETE]}
AS
BEGIN
-- T-SQL 邏輯
END;
CREATE TRIGGER tgr_classes_insert ON classes
AFTER INSERT
AS
BEGIN
DECLARE @id INT, @name VARCHAR(20), @temp INT;
SELECT @id = id, @name = name FROM inserted;
SET @name = @name + CAST(@id AS VARCHAR);
SET @temp = @id / 2;
INSERT INTO student (name, age, score, cid) VALUES (@name, 18 + @id, @temp, @id);
PRINT '學生聯動新增成功';
END;
CREATE TRIGGER tgr_classes_delete ON classes
AFTER DELETE
AS
BEGIN
PRINT '備份中...';
IF OBJECT_ID('classesBackup', 'U') IS NOT NULL
INSERT INTO classesBackup SELECT name, createDate FROM deleted;
ELSE
SELECT * INTO classesBackup FROM deleted;
PRINT '備份完成';
END;
CREATE TRIGGER tgr_classes_update ON classes
AFTER UPDATE
AS
BEGIN
DECLARE @oldName VARCHAR(20), @newName VARCHAR(20);
SELECT @oldName = name FROM deleted;
IF EXISTS (SELECT 1 FROM student WHERE name LIKE '%' + @oldName + '%')
BEGIN
SELECT @newName = name FROM inserted;
UPDATE student SET name = REPLACE(name, @oldName, @newName)
WHERE name LIKE '%' + @oldName + '%';
PRINT '級聯修改完成';
END
ELSE PRINT '無需修改 student';
END;
CREATE TRIGGER tgr_classes_update_column ON classes
AFTER UPDATE
AS
BEGIN
IF UPDATE(createDate) -- 僅當 createDate 被修改時觸發
BEGIN
RAISERROR('系統提示:班級建立時間不可修改!', 16, 1);
ROLLBACK TRANSACTION;
END
END;
CREATE TRIGGER tgr_classes_insteadOf ON classes
INSTEAD OF DELETE
AS
BEGIN
DECLARE @id INT, @name VARCHAR(20);
SELECT @id = id, @name = name FROM deleted;
DELETE FROM student WHERE cid = @id; -- 先刪子表
DELETE FROM classes WHERE id = @id; -- 再刪主表
PRINT '級聯刪除完成:' + @name;
END;
CREATE TABLE log (id INT IDENTITY PRIMARY KEY, action VARCHAR(20), createDate DATETIME DEFAULT GETDATE());
CREATE TRIGGER tgr_student_log ON student
AFTER INSERT, UPDATE, DELETE
AS
BEGIN
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 IF EXISTS (SELECT 1 FROM deleted)
INSERT INTO log(action) VALUES ('DELETED');
END;
| 操作 | 指令 |
|---|---|
| 查看所有觸發器 | SELECT * FROM sys.triggers; 或 SELECT * FROM sys.objects WHERE type = 'TR'; |
| 查看觸發事件 | SELECT te.* FROM sys.trigger_events te JOIN sys.triggers t ON t.object_id = te.object_id WHERE t.parent_class = 0 AND t.name = 'tgr_valid_data'; |
| 查看定義原始碼 | EXEC sp_helptext 'tgr_message'; |
| 啟用/停用 | ENABLE TRIGGER tgr_message ON student; / DISABLE TRIGGER tgr_message ON student; |
| 修改 | ALTER TRIGGER ... (語法同 CREATE) |
| 刪除 | DROP TRIGGER tgr_message; |
inserted/deleted 可能包含多行,**禁止**假設單行 (如 `SELECT @id = id FROM inserted`),需用 `JOIN`/`EXISTS`/集合操作。觸發器是資料庫端**被動式業務邏輯**的利器,適用於稽核、衍生欄位維護、跨表一致性、軟刪除等場景。掌握 inserted/deleted 集合語義、AFTER vs INSTEAD OF 差異、列級 `UPDATE()` 判斷,並遵守「輕量、集合、無巢狀、有文檔」四原則,即能寫出健壯可維護的觸發器。