SQL Server 觸發器
by:授客 QQ:1033553122
什么是觸發器
1.觸發器是對表進行插入、更新、刪除操作時自動執行的存儲過程
2.觸發器通常用於強制業務規則
3.觸發器是一種高級約束,可以定義比check等約束更為復雜的約束
可執行復雜的sql語句(if/while/case)
可引用其它表中的列
4.觸發器定義在特定的表上,與表相關
5.自動觸發執行,不能直接調用
6.是一個事務(可回滾,不能手動提交)
觸發器的類型
delete觸發器 當刪除表中記錄時觸發,自動執行觸發器所定義的SQL語句
insert觸發器 當向表中插入數據時觸發,自動執行觸發器所定義的SQL語句
update觸發器 當更新表中某列、多列時觸發,自動執行觸發器所定義的SQL語句
deleted 和 inserted 表
觸發器觸發時
1.系統自動在內存中創建deleted表或inserted表
2.只讀,不允許修改;觸發器執行完后,自動刪除
inserted:用於存儲 INSERT 和 UPDATE 語句所影響的行的副本。
1.在執行INSERT 或 UPDATE 語句時,新加行被同時添加到 inserted 表和觸發器表中,所以inserted表臨時保存了插入或更新后的記錄行
2.可以從inserted中檢查插入的數據是否滿足業務需求,如果不滿足,則向用戶報告錯誤消息,並回滾插入操作
deleted表:表用於存儲 DELETE 和 UPDATE 語句所影響的行的副本
1.在執行 DELETE 或 UPDATE 語句時,行從觸發器表中刪除,並傳輸到 deleted 表中,所以deleted表臨時保存了刪除或更新前的記錄行
2.可從deleted表中檢查被刪除的數據是否滿足業務需求, 如果不滿足,則向用戶報告錯誤消息,並回滾插入操作
注意:更新(UPDATE)語句類似於在刪除之后執行插入;首先舊行被復制到 deleted 表中,然后新行被復制到觸發器表和 inserted 表中

如何創建觸發器
1.創建觸發器的語法
create trigger trigger_name
on table_name
for [delete|insert|update]
as
t-sql語句
go
2.insert 觸發器的工作原理
說明:
1. 執行insert插入語句,在表中插入數據行
2. 觸發insert觸發器,向系統臨時表inserted表中插入新行的副本
3. 觸發器檢查inserted表中插入的新行數據,確定是搜需要回滾或執行其他操作。
問題:
解決上述的銀行取款問題:當向交易信息表(transInfo)中插入一條交易信息時,我們應自動更新對應帳戶的余額。
分析:
1. 在交易信息表上創建 INSERT 觸發器2.從inserted臨時表中獲取插入的數據行
3.根據交易類型(transType)字段的值是存入/支取,
4.增加/減少對應帳戶的余額。
create trigger trig_transInfo
on transInfo
for insert
as
declare @type char(4),@outMoney money
declare @myCardID char(10),@blance money
#從inserted表中獲取交易類型、教員金額等
select @type=transType,@outMoney=transMoney,@myCardID=cardID from inserted
#根據交易類型,減少或增加對應卡號的余額
if(@type=’支取’)
update bank set currentMoney=currentMoney-@outMoney where cardID=@myCardID
else
update bank set currentMoney=currentMoney+@outMoney where cardID=@myCardID
……
go
delete觸發器
問題
當刪除交易信息表時,要求自動備份被刪除的數據到表backupTable中
分析:
在交易信息表上創建delete觸發器
被刪除的數據可從deleted表中獲取
注:delete刪除觸發器的典型應用就是銀行系統中的數據備份。當交易記錄過多時,為了不影響數據訪問的速度,交易信息表需要定期刪除部分數據。當刪除數據時,一般需要自動備份,以便將來的客戶查詢、數據恢復或年終統計等。
create trigger trig_delete_transInfo
on transInfo
for delete
as
print’開始備份數據,請稍后……’
if not exists(select * from sysobjects where name=’backupTable’)
select * into backupTable from deleted
else
insert into backupTable select * from deleted
print’備份數據成功,備份表中的數據為:’
select * from backupTable
go
update觸發器
update觸發器的工作原理
說明:
執行更新操作,例如把李四的余額改為20001元。
更新操作可以看出兩步:
1.刪除李四原有的數據:李四 1000 0002 1,將數據備份到deleted表中。
2.再插入新行:李四 1000 0002 20001,將數據備份到inserted表中。
最后看起來就是把余額從1元修改為20001元了。
所以:
如果我們希望查看修改前的原始數據,可以查看表deleted 。
如果我們希望查看修改后的數據,可以查看表inserted 。
問題:跟蹤用戶的交易,交易金額超過20000元,則取消交易,並給出錯誤提示。
分析:
在bank表上創建UPDATE觸發器
修改前的數據可以從deleted表中獲取;修改后的數據可以從inserted表中獲取
注解:update更新觸發器主要用於跟蹤數據的變化。典型的應用就是銀行系統中,為了安全起見,一般要求每次交易金額不能超過一定的數額。
用 戶每次的交易金額,我們可以從交易信息表中直接獲取,也可以根據帳號信息表中余額的變化來獲取。交易的方式較多,用戶可能用卡消費,也可能用存折消費,存 折的交易信息與卡略有不同,可能不會將交易信息存放在交易表中,而保存在其它表中。但存折和卡對應的帳號余額只有一個。所以更安全的方案就是:根據賬戶信 息表中余額的變化來獲取交易金額。為了獲取交易余額的變化,我們應該在賬戶的信息表上創建 update 觸發器
create trigger trig_updadte_bank
on bank
for update
as
declare @beforeMoney money,@after Money money
select @beforeMoney=currentMoney from deleted
select @afterMoney=currentMoney from inserted
if abs(@afterMoney-@beforMoney)>20000
begin
print’交易金額:’+convert(varchar(8),abs(beforeMoney-afterMoney))
raiserror(‘每筆交易不能超過2萬元’,交易失敗’,16,1)
rollback transtraction
end
go
UPDATE觸發器除了跟蹤數據的變化(修改)外,還可以檢查是否修改了某列的數據
使用UPDATE(列)函數檢測是否修改了某列
問題:
交易日期一般由系統自動產生,默認為當前日期。為了安全起見,一般禁止修改,以防舞弊
UPDATE(列名)函數可以檢測是否修改了某列
注:UPDATE( )函數:測試在指定的列上進行的 INSERT 或 UPDATE 修改。
create trigger trig_update_transInfo
on transInfo
for update
as
if update(transDate) --檢查是否修改了交易日期列transDate
begin
print’交易失敗’
raiserror(‘安全警告:交易日期不能修改,由系統自動產生’,16,1)
rollback transtraction
end
go
總結:
觸發器是在對表進行插入、更新或刪除操作時自動執行的存儲過程,觸發器通常用於強制業務規則
觸發器還是一個特殊的事務單元,當出現錯誤時,可以執行ROLLBACK TRANSACTION回滾撤銷操作
觸發器一般都需要使用臨時表:deleted表和inserted表,它們存放了被刪除或插入的記錄行副本
觸發器類型:INSERT觸發器、UPDATE觸發器、DELETE觸發器