SQL?Server觸發(fā)器常見應用場景和注意事項詳解
一、什么是觸發(fā)器(Trigger)?
觸發(fā)器(Trigger)是一種特殊的存儲過程,它不會被人為調(diào)用,而是在對表執(zhí)行特定操作時自動觸發(fā)執(zhí)行。
常見觸發(fā)條件包括:
INSERT(插入數(shù)據(jù))UPDATE(更新數(shù)據(jù))DELETE(刪除數(shù)據(jù))
可以理解為:
當表發(fā)生變化時,數(shù)據(jù)庫自動執(zhí)行的一段“監(jiān)聽程序”。
觸發(fā)器的典型用途
數(shù)據(jù)審計(記錄誰改了什么數(shù)據(jù))
數(shù)據(jù)校驗(防止非法操作)
自動維護關聯(lián)數(shù)據(jù)
業(yè)務規(guī)則約束(如庫存不能為負)
二、觸發(fā)器的分類
SQL Server 中主要有兩類觸發(fā)器:
1. DML 觸發(fā)器(針對表)
作用對象:INSERT / UPDATE / DELETE
分為兩種:
(1)AFTER 觸發(fā)器(之后觸發(fā))
在操作完成后執(zhí)行。
CREATE TRIGGER trg_AfterInsert
ON Student
AFTER INSERT
AS
BEGIN
PRINT '插入數(shù)據(jù)成功'
END(2)INSTEAD OF 觸發(fā)器(替代執(zhí)行)
替代原本的操作執(zhí)行,常用于視圖或復雜邏輯控制。
CREATE TRIGGER trg_InsteadDelete
ON Student
INSTEAD OF DELETE
AS
BEGIN
PRINT '禁止刪除學生記錄'
END2. DDL 觸發(fā)器(針對數(shù)據(jù)庫級操作)
用于監(jiān)聽:
CREATE TABLE
DROP TABLE
ALTER TABLE
CREATE LOGIN 等
CREATE TRIGGER trg_DDL
ON DATABASE
FOR DROP_TABLE
AS
BEGIN
PRINT '禁止刪除表結(jié)構'
END三、Inserted 與 Deleted 表(核心概念)
在 DML 觸發(fā)器中,SQL Server 提供了兩個虛擬表:
| 操作 | Inserted 表 | Deleted 表 |
|---|---|---|
| INSERT | 新數(shù)據(jù) | 空 |
| DELETE | 空 | 原數(shù)據(jù) |
| UPDATE | 新數(shù)據(jù) | 舊數(shù)據(jù) |
示例:記錄學生表修改日志
CREATE TRIGGER trg_UpdateLog
ON Student
AFTER UPDATE
AS
BEGIN
INSERT INTO StudentLog(StudentID, OldName, NewName, UpdateTime)
SELECT d.ID, d.Name, i.Name, GETDATE()
FROM deleted d
JOIN inserted i ON d.ID = i.ID
END四、觸發(fā)器的常見應用場景
1. 數(shù)據(jù)審計(日志記錄)
CREATE TRIGGER trg_InsertLog
ON Orders
AFTER INSERT
AS
BEGIN
INSERT INTO OrderLog(OrderID, CreateTime)
SELECT ID, GETDATE() FROM inserted
END2. 數(shù)據(jù)校驗(防止非法數(shù)據(jù))
例如:禁止工資為負數(shù)
CREATE TRIGGER trg_CheckSalary
ON Employee
AFTER INSERT, UPDATE
AS
BEGIN
IF EXISTS (SELECT 1 FROM inserted WHERE Salary < 0)
BEGIN
ROLLBACK
RAISERROR('工資不能為負數(shù)',16,1)
END
END3. 維護關聯(lián)數(shù)據(jù)(如庫存)
當訂單插入時,自動減少庫存。
五、觸發(fā)器的注意事項(非常重要)
1. 觸發(fā)器是“針對集合”的,不是單行
錯誤寫法(假設只有一行):
SELECT @id = ID FROM inserted
正確思維:要按多行數(shù)據(jù)處理。
2. 不要在觸發(fā)器中寫復雜業(yè)務邏輯
原因:
難調(diào)試
性能差
容易造成死鎖
影響主業(yè)務SQL執(zhí)行
觸發(fā)器適合做:
? 校驗
? 日志
? 簡單數(shù)據(jù)同步
不適合:
? 復雜計算
? 調(diào)用外部接口
? 長事務邏輯
3. 謹慎使用 ROLLBACK
觸發(fā)器中一旦 ROLLBACK,原 SQL 操作也會失敗。
4. 注意遞歸觸發(fā)
如果觸發(fā)器中再次修改本表,可能導致無限循環(huán)。
可關閉遞歸:
ALTER DATABASE dbname SET RECURSIVE_TRIGGERS OFF
六、觸發(fā)器與存儲過程的區(qū)別
| 對比項 | 觸發(fā)器 | 存儲過程 |
|---|---|---|
| 是否自動執(zhí)行 | 是 | 否 |
| 是否可傳參 | 否 | 是 |
| 調(diào)用方式 | 系統(tǒng)觸發(fā) | 手動調(diào)用 |
| 使用場景 | 監(jiān)聽數(shù)據(jù)變化 | 業(yè)務邏輯處理 |
七、最佳實踐總結(jié)
推薦使用場景:
數(shù)據(jù)審計日志
簡單校驗規(guī)則
防誤操作保護
數(shù)據(jù)同步
不推薦使用場景:
核心業(yè)務邏輯
高并發(fā)復雜處理
跨系統(tǒng)調(diào)用
一句話原則:
觸發(fā)器 = 數(shù)據(jù)層的“守門員”,不是業(yè)務層的“指揮官”。
八、結(jié)語
SQL Server 觸發(fā)器是一把“雙刃劍”:
用得好:提高數(shù)據(jù)安全性與一致性
用不好:降低性能、增加維護成本
建議遵循:
少用、慎用、簡單用。
把復雜業(yè)務邏輯放在:
存儲過程
服務層(Java / C#)
應用程序中處理
面試回答話術(簡潔版)
“觸發(fā)器主要用于實現(xiàn)復雜的業(yè)務完整性、審計日志、自動更新冗余統(tǒng)計字段以及軟刪除。但我清楚它的代價:隱式執(zhí)行、難以調(diào)試、容易引發(fā)性能問題和死鎖。
使用時我會特別注意:
基于集合處理 inserted/deleted,絕不用游標或逐行操作;
避免在觸發(fā)器內(nèi)進行耗時操作或開啟新事務;
關閉遞歸觸發(fā)器(除非有明確需求);
對批量操作做充分測試;
優(yōu)先考慮用約束、計算列或應用層邏輯替代觸發(fā)器。
總的來說,觸發(fā)器是最后的手段,能不用就不用;但遇到必須保證數(shù)據(jù)強一致性且無法用其他方法實現(xiàn)時,它是個有效的工具。”
總結(jié)
到此這篇關于SQL Server觸發(fā)器常見應用場景和注意事項詳解的文章就介紹到這了,更多相關SQL Server觸發(fā)器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Sql Server中Substring函數(shù)的用法實例解析
在sqlserver中substring函數(shù)是用來處理字符串的,常用于字符串截取了,下面我來給大家介紹下Sql Server中Substring函數(shù)的用法實例解析,需要的朋友參考下吧2016-12-12
t-sql/mssql用命令行導入數(shù)據(jù)腳本的SQL語句示例
這篇文章主要介紹了t-sql或mssql用命令行導入數(shù)據(jù)腳本的SQL語句示例,大家參考使用吧2013-11-11
解決Navicat連接本地sqlserver數(shù)據(jù)庫成功后沒有庫表數(shù)據(jù)的問題
本文主要給大家介紹了如何解決Navicat連接本地sqlserver數(shù)據(jù)庫成功后沒有庫表數(shù)據(jù)的問題,文中有詳細的原因分析和解決方法,具有一定的參考價值,需要的朋友可以參考下2023-10-10
SQL Server 數(shù)據(jù)庫分區(qū)分表(水平分表)詳細步驟
最近幾個擔心網(wǎng)站數(shù)據(jù)量大會影響sqlserver數(shù)據(jù)庫的性能,所以提前將數(shù)據(jù)庫分表處理好,下面是ExceptionalBoy同學分享的詳細方法,需要的朋友可以參考下2021-03-03
解決無法在unicode和非unicode字符串數(shù)據(jù)類型之間轉(zhuǎn)換的方法詳解
本篇文章是對無法在unicode和非unicode字符串數(shù)據(jù)類型之間轉(zhuǎn)換的解決方法進行了詳細的分析介紹,需要的朋友參考下2013-06-06
動態(tài)SQL中返回數(shù)值的實現(xiàn)代碼
最近在做一個paypal抓取數(shù)據(jù)的程序,由于所有字段和paypal之間存在對應映射的關系,所以所有的sql語句必須得拼接傳到存儲過程里去執(zhí)行2011-12-12
淺析SQL Server的嵌套存儲過程中使用同名的臨時表怪像
這篇文章主要介紹了淺析SQL Server的嵌套存儲過程中使用同名的臨時表怪像,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-02-02

