--維護數據庫--
--觸發器--
--概述:
觸發器是一種特殊類型的存儲過程,用來強制執行業務規則。在調用執上,觸發器不能像存儲過程那樣可以由用戶通過T-SQL語句直接調用,而是需要有數據庫所發生的insert、update、delete事件的執行來激發觸發器的自動執行。因此在創建和使用觸發器時,需要考慮好觸發事件的執行和被觸發事件後,再設計和創建觸發器,已完成用戶需求。
觸發器可以向約束一樣,在數據表和視圖中的數據發生改變時強制執行業務規則。在某種角度上,觸發器要優於約束,因為觸發器可以包含使用T-SQL語言編寫的復雜代碼,可以涉及其他數據表中的數據。約束能夠完成的功能觸發器都能可以做到,但它所給出的解決方案並不一定總是最好的。因此,約束和觸發器在不同情況下各有優勢。
與存儲過程一樣,創建觸發器的語句必須存在於同一個批處理中。
--分類:按照觸發事件的語言分類,可以將觸發器分成DML觸發器和DDL觸發器。
1)DML觸發器:是指可以被對數據表的insert、update和delete操作所觸發的觸發器。
2)DDL觸發器:是指可以被數據庫對象的create、alter、drop操作所觸發的c觸發器。
兩種觸發器的創建、修改和刪除方法相似。
--DML觸發器(詳細介紹):
注:DML觸發器按照觸發器的觸發和執行事件的不同,可分為after類型觸發器和instead of類型觸發器。
♦after類型觸發器(後觸發觸發器):如果把被觸發器封裝的T-SQl語句所代表的事件稱為“被觸發事件”,把觸發觸發器執行的insert、update或者delete語句所代表的事件稱為“觸發事件”。after類型觸發器即是時指“觸發事件”成功執行完畢後,“被觸發事件”執行的觸發器。
after類型觸發器只能創建在數據表上,而不能創建在視圖上。一張數據表可以創建多個因同一觸發操作而生成的觸發器,但同一觸發器操作所激發的觸發器的執行順序隨機,可以通過對觸發器禁用和恢復的方法設置執行那個觸發器。
♦instead of類型觸發器(替換觸發器):簡單地說,instead of類型的觸發器當“觸發事件”發生時,系統並不執行“觸發事件”的具體操作(比如insert、update或者delete數據),而是直接執行“被觸發事件”。
instead of類型觸發器可以定義在表上和視圖上。對於每個觸發操作(insert、update或delete)只能定義一個instead of類型觸發器。
--inserted表和deleted表
注:inserted表和deleted表是系統為每個觸發器准備的臨時表,存放於內存中。當觸發器被觸發執行時,inserted表和deleted表將記錄觸發器執行過程中設計的每條記錄信息,以方便用戶使用和查詢。inserted表和deleted表中的記錄只能查看,不能修改,當觸發器執行完畢後,與之相關的臨時表也隨之刪除。
沒有“updated”表,update作為修改操作,既相當與刪除數據再添加數據,因此,當觸發操作作為update命令時,即生成deleted表又生成inserted表。
♦inserted表
inserted表用來存放當觸發操作為insert命令所產生的數據信息。該表的結構與insert命令所作用的表結構相同,表中信息作為副本存儲,且只存儲新發生的記錄信息。
♦deleted表
deleted表用來存放當觸發操作為delete命令所產生的數據信息。該表的結構與delete命令所作用的表結構相同,表中信息作為副本存儲,且只存儲新發生的記錄信息。
--觸發器管理--
--創建觸發器(create trigger)--
注:在SQL Server中,觸發器可以是使用“管理器”和T-SQL語言兩種方式創建。執行觸發器其實即是執行了定義觸發器時的觸發命令(insert、update和delete)。
create trigger 觸發器名 --create trigger命令表示創建觸發器,該命令要求是批處理中的第一句話。
on 數據表名 --“on 數據表名”指“觸發事件”發生的數據表。
[with encryption] --with encryption語句可以對創建不同類型的觸發器。
after | instead of [insert] [, update] [,delete] --after和instead of是可選項,用來創建不同類型的觸發器。insert、update、delete是執行操作,可以單選也可以多選,沒有先後順序。
as --as後的T-SQl語句是“被觸發事件”。
T-SQl語句
例1:(after類型觸發器)(創建名為“t_客戶信息表_電話”的觸發器,當“商品管理數據庫”中“客戶信息表”的客戶編號為20130001的客戶聯系電話修改為13600003333操作成功執行後,在結果打印一條“記錄已修改!”的提示信息。) --創建觸發器 use 商品管理數據庫 go create trigger t_客戶信息表_電話 on 客戶信息表 after update --after類型觸發器 as print '記錄已修改!' select*from 客戶信息表 --執行“觸發事件”激發觸發器執行 use 商品管理數據庫 go update 客戶信息表 set 聯系電話='13600003333' where 客戶編號='20130001' go 例2:(instead of類型觸發器)(創建名為“t_客戶信息表_電話no”的觸發器,當“商品管理數據庫”中“客戶信息表”的客戶編號為20130001的客戶聯系電話修改為13600004444時,不執行修改操作,並在結果打印一條“記錄未修改!”的提示信息。) --創建觸發器 use 商品管理數據庫 go create trigger t_客戶信息表_電話no on 客戶信息表 instead of update as print '記錄未修改!' select*from 客戶信息表 --執行“觸發事件”激發觸發器執行 use 商品管理數據庫 go update 客戶信息表 set 聯系電話='13600004444' where 客戶編號='20130001' 例3:(after類型觸發器)(當“商品管理數據庫”中有商品售出時,除了向“銷售信息表”中添加銷售記錄之外,還應該為“庫存信息表”中相應商品減掉與銷售數量等值的庫存數量。創建名為“t_銷售表_庫存表”的觸發器。) use 商品管理數據庫 go create trigger t_銷售表_庫存表 on 銷售信息表 after insert as update 庫存信息表 set 庫存數量=庫存數量-(select 銷售數量 from inserted) --查詢“庫存信息表”商品編號為11110003的商品現有數量 select*from 庫存信息表 where 商品編號='11110003' --向“銷售信息表”添加商品編號wei11110003的商品售出10個記錄,以激發存儲過程。 use 商品管理數據庫 go insert 銷售信息表 values(8,'11110003',2.5,10,50,'2012-12-21',20130004) --查詢“庫存信息表”商品編號為11110003的商品現有數量,與之前作比較 select*from 庫存信息表 where 商品編號='11110003'理解例子
--查看觸發器
注:由於觸發器是特殊的存儲過程,因此可以使用系統存儲過程查看觸發器相關信息。
exec 系統存儲過程 用戶自定義存儲過程名
--sp_depends:查看觸發器的依賴關系
--sp_help:查看觸發器的創建信息
--sp_helptext:查看觸發器的創建文本(被加密的觸發器無法查看)
exec sp_helptrigger 數據表名
--sp_helptrigger:查看某張數據表中創建了那些類型的觸發器
例:(查看“商品管理數據庫”的“銷售信息表”中創建了那些觸發器,查看已創建的觸發器信息)
use 商品管理數據庫
go
exec sp_helptrigger 銷售信息表
例:
use 商品管理數據庫
go
exec sp_depends t_銷售表_庫存表
exec sp_help t_銷售表_庫存表
exec sp_helptext t_銷售表_庫存表
--修改觸發器
注:無論是修改觸發器名稱還是功能,都會對該觸發器有關聯的數據表或數據表中的字段產生影響,因此請根據需要謹慎修改。
類似於修改存儲過程,修改觸發器也相當於刪除了原來的觸發器功能,創建了新的觸發器功能。
1)
alter trigger 觸發器名
on 數據表名
[with encryption]
after | instead of [insert] [, update] [, delete]
as
T-SQL語句
2)
也可以使用系統存儲過程sp_rename為觸發器重命名:
exec sp_rename 原觸發器名,新觸發器名
--啟用觸發器
enable trigger 觸發器名 on 數據表名
例:(啟用“銷售信息表”中的觸發器“t__銷售表_庫存表”)
use 商品管理數據庫
go
disable trigger t__銷售表_庫存表 on 銷售信息表
--禁用觸發器
disable trigger 觸發器名 on 數據表名
例:(禁用“銷售信息表”中的觸發器“t__銷售表_庫存表”)
use 商品管理數據庫
go
disable trigger t__銷售表_庫存表 on 銷售信息表
--刪除觸發器
drop trigger 觸發器名
例:
use 商品管理數據庫
go
drop trigger t_銷售表_庫存表
注:"--"可看成說明或者注釋文本