觸發器實際上就是一種特殊類型的存儲過程,其特殊性表如今:它是在執行某些特定的T-SQL語句時自動的。前端
11.1 觸發器簡介sql
觸發器實際上就是一種特殊類型的存儲過程,它是在執行某些特定的T-SQL語句時自動執行的一種存儲過程。在SQL Server 2005中,根據SQL語句的不一樣,把觸發器分爲兩類:一類是DML觸發器,一類是DLL觸發器。數據庫
11.1.1 觸發器的概念和做用編程
在SQL Server 2005裏,能夠用兩種方法來保證數據的有效性和完整性:約束(check)和觸發器(Trigger)。約束是直接設置於數據表內,只能現實一些比較簡 單的功能操做,如:實現字段有效性和惟一性的檢查、自動填入默認值、確保字段數據不重複(即主鍵)、確保數據表對應的完整性(即外鍵)等功能。服務器
觸發器是針對數據表(庫)的特殊的存儲過程,當這個表發生了 Insert、Update或Delete操做時,會自動激活執行的,能夠處理各類複雜的操做。在SQL Server 2005中,觸發器有了更進一步的功能,在數據表(庫)發生Create、Alter和Drop操做時,也會自動激活執行。架構
觸發器經常使用的一些功能以下:編輯器
l 完成比約束更復雜的數據約束:觸發器能夠實現比約束更爲複雜的數據約束ide
l 檢查所作的SQL是否容許:觸發器能夠檢查SQL所作的操做是否被容許。例如:在產品庫存表裏,若是要刪除一條產品記錄,在刪除記錄時,觸發器能夠檢查該產品庫存數量是否爲零,若是不爲零則取消該刪除操做。函數
l 修改其它數據表裏的數據:當一個SQL語句對數據表進行操做的時候,觸發器能夠根據該SQL語句的操做狀況來對另外一個數據表進行操做。例如:一個訂單取消的時候,那麼觸發器能夠自動修改產品庫存表,在訂購量的字段上減去被取消訂單的訂購數量。工具
l 調用更多的存儲過程:約束的自己是不能調用存儲過程的,可是觸發器自己就是一種存儲過程,而存儲過程是能夠嵌套使用的,因此觸發器也能夠調用一個或多過存儲過程。
l 發送SQL Mail:在SQL語句執行完以後,觸發器能夠判斷更改過的記錄是否達到必定條件,若是達到這個條件的話,觸發器能夠自動調用SQL Mail來發送郵件。例如:當一個訂單交費以後,能夠物流人員發送Email,通知他儘快發貨。
l 返回自定義的錯誤信息:約束是不能返回信息的,而觸發器能夠。例如插入一條重複記錄時,能夠返回一個具體的友好的錯誤信息給前臺應用程序。
l 更改本來要操做的SQL語句:觸發器能夠修改本來要操做的SQL語句,例如本來的SQL語句是要刪除數據表裏的記錄,但該數據表裏的記錄是最要記錄,不容許刪除的,那麼觸發器能夠不執行該語句。
l 防止數據表構結更改或數據表被刪除:爲了保護已經建好的數據表,觸發器能夠在接收到Drop和Alter開頭的SQL語句裏,不進行對數據表的操做。
11.1.2 觸發器的種類
在SQL Server 2005中,觸發器能夠分爲兩大類:DML觸發器和DDL觸發器
l DML觸發器:DML觸發器是當數據庫服務器中發生數據操做語言(Data Manipulation Language)事件時執行的存儲過程。DML觸發器又分爲兩類:After觸發器和Instead Of觸發器
l DDL觸發器:DDL觸發器是在響應數據定義語言(Data Definition Language)事件時執行的存儲過程。DDL觸發器通常用於執行數據庫中管理任務。如審覈和規範數據庫操做、防止數據庫表結構被修改等。
11.2 DML觸發器的分類
SQL Server 2005的DML觸發器分爲兩類:
l After觸發器:這類觸發器是在記錄已經改變完以後(after),纔會被激活執行,它主要是用於記錄變動後的處理或檢查,一旦發現錯誤,也能夠用Rollback Transaction語句來回滾本次的操做。
l Instead Of觸發器:這類觸發器通常是用來取代本來的操做,在記錄變動以前發生的,它並不去執行原來SQL語句裏的操做(Insert、Update、Delete),而去執行觸發器自己所定義的操做。
11.3 DML觸發器的工做原理
在SQL Server 2005裏,爲每一個DML觸發器都定義了兩個特殊的表,一個是插入表,一個是刪除表。這兩個表是建在數據庫服務器的內存中的,是由系統管理的邏輯表,而不是真正存儲在數據庫中的物理表。對於這兩個表,用戶只有讀取的權限,沒有修改的權限。
這兩個表的結構與觸發器所在數據表的結構是徹底一致的,當觸發器的工做完成以後,這兩個表也將會從內存中刪除。
插入表裏存放的是更新前的記錄:對於插入記錄操做來講,插入表裏存放的是要插入的數據;對於更新記錄操做來講,插入表裏存放的是要更新的記錄。
刪除表裏存放的是更新後的記錄:對於更新記錄操做來講,刪除表裏存放的是更新前的記錄(更新完後即被刪除);對於刪除記錄操做來講,刪除表裏存入的是被刪除的舊記錄。
下面看一下觸發器的工做原理。
11.3.1 After觸發器的工做原理
After觸發器是在記錄更變完以後才被激活執行的。以刪除記錄爲 例:當SQL Server接收到一個要執行刪除操做的SQL語句時,SQL Server先將要刪除的記錄存放在刪除表裏,而後把數據表裏的記錄刪除,再激活After觸發器,執行After觸發器裏的SQL語句。執行完畢以後, 刪除內存中的刪除表,退出整個操做。
仍是舉上面的例子:在產品庫存表裏,若是要刪除一條產品記錄,在刪除記錄時,觸發器能夠檢查該產品庫存數量是否爲零,若是不爲零則取消刪除操做。看一下數據庫是怎麼操做的:
(1)接收SQL語句,將要從產品庫存表裏刪除的產品記錄取出來,放在刪除表裏。
(2)從產品庫存表裏刪除該產品記錄。
(3)從刪除表裏讀出該產品的庫存數量字段,判斷是否是爲零,若是爲零的話,完成操做,從內存裏清除刪除表;若是不爲零的話,用Rollback Transaction語句來回滾操做。
11.3.2 Instead Of觸發器的工做原理
Instead Of觸發器與After觸發器不一樣。After觸發器是在Insert、Update和Delete操做完成後才激活的,而Instead Of觸發器,是在這些操做進行以前就激活了,而且再也不去執行原來的SQL操做,而去運行觸發器自己的SQL語句。
11.4 設計DML觸發器的注意事項及技巧
在瞭解觸發器的種類和工做理由以後,如今能夠開始動手來設計觸發器了,不過在動手以前,還有一些注意事項必須先了解一下:
11.4.1 設計觸發器的限制
在觸發器中,有一些SQL語句是不能使用的,這些語句包括:
表11.1 在DML觸發器中不能使用的語句
不能使用的語句 |
語句功能 |
Alter Database |
修改數據庫 |
Create Database |
新建數據庫 |
Drop Database |
刪除數據庫 |
Load Database |
導入數據庫 |
Load Log |
導入日誌 |
Reconfigure |
更新配置選項 |
Restore Database |
還原數據庫 |
Restore Log |
還原數據庫日誌 |
另外,在對做爲觸發操做的目標的表或視圖使用了下面的SQL語句時,不容許在DML觸發器裏再使用這些語句:
表11.2 在目標表中使用過的,DML觸發器不能再使用的語句
不能使用的語句 |
語句功能 |
Create Index |
創建索引 |
Alter Index |
修改索引 |
Drop Index |
刪除索引 |
DBCC Dbreindex |
從新生成索引 |
Alter Partition Function |
經過拆分或合併邊界值更改分區 |
Drop Table |
刪除數據表 |
Alter Table |
修改數據表結構 |
11.4.2 如何在觸發器取得字段修改前和修改後的數據
上面介紹過,SQL Server 2005在爲每一個觸發器都定義了兩個虛擬表,一個是插入表(inserted),一個是刪除表(deleted),如今把這兩個表存放的數據列表說明一下:
表11.3 插入/刪除表的功能
激活觸發器的動做 |
Inserted表 |
Deleted表 |
Insert |
存放要插入的記錄 |
|
Update |
存放要更新的記錄 |
存放更新前的舊記錄 |
Delete |
存放要刪除的舊記錄 |
以上面刪除庫存產品記錄爲例,在刪除時觸發器要判斷庫存數量是否爲零,那麼判斷就應該這麼寫:
If (Select 庫存數量 From Deleted)>0
Begin
Print ‘庫存數量大於零時不能刪除此記錄’
Rollback Transaction
End
11.4.3 其餘注意事項
l After觸發器只能用於數據表中,Instead Of觸發器能夠用於數據表和視圖上,但兩種觸發器都不能夠創建在臨時表上。
l 一個數據表能夠有多個觸發器,可是一個觸發器只能對應一個表。
l 在同一個數據表中,對每一個操做(如Insert、Update、Delete)而言能夠創建許多個After觸發器,但Instead Of觸發器針對每一個操做只有創建一個。
l 若是針對某個操做即設置了After觸發器又設置了Instead Of觸發器,那麼Instead of觸發器必定會激活,而After觸發器就不必定會激活了。
l Truncate Table語句雖然相似於Delete語句能夠刪除記錄,可是它不能激活Delete類型的觸發器。由於Truncate Table語句是不記入日誌的。
l WRITETEXT語句不能觸發Insert和Update型的觸發器。
l 不一樣的SQL語句,能夠觸發同一個觸發器,如Insert和Update語句均可以激活同一個觸發器。
11.5 設計After觸發器
在瞭解觸發器及其種類、做用、工做原理以後,下面詳細講述一下要怎麼去設計及創建觸發器。
11.5.1 設計簡單的After觸發器
下面用實例設計一個簡單的After Insert觸發器,這個觸發器的做用是:在插入一條記錄的時候,發出「又添加了一種產品」的友好提示。
(1)啓動Management Studio,登陸到指定的服務器上。
(2)在如圖11.1所示界面的【對象資源管理器】下選擇【數據庫】,定位到【Northwind】數據庫à【表】à【dbo.產品】,並找到【觸發器】項。
圖11.1 定位到觸發器
(3)右擊【觸發器】,在彈出的快捷菜單中選擇【新建觸發器】選項,此時會自動彈出【查詢編輯器】對話框,在【查詢編輯器】的編輯區裏SQL Server已經預寫入了一些創建觸發器相關的SQL語句,如圖11.2所示。
圖11.2 SQL Server 2005預寫的觸發器代碼
(4)修改【查詢編輯器】裏的代碼,將從「CREATE」開始到「GO」結束的代碼改成如下代碼:
CREATE TRIGGER 產品_Insert
ON 產品
AFTER INSERT
AS
BEGIN
print '又添加了一種產品'
END
GO
若是有興趣的話,也能夠去修改一下如圖11.2中綠色部分的版權信息。
(5)單擊工具欄中的【分析】按鈕 ,檢查一下是否語法有錯,如圖11.3所示,若是在下面的【結果】對話框中出現「命令已成功完成」,則表示語法沒有錯誤。
圖11.3 檢查語法
(6)語法檢查無誤後,單擊【執行】按鈕,生成觸發器。
(7)關掉查詢編輯器對話框,刷新一下觸發器對話框,能夠看到剛纔創建的【產品_Insert】觸發器,如圖11.4所示。
圖11.4 建好的觸發器
創建After Update觸發器、After Delete觸發器和創建After Insert觸發器的步驟一致,不一樣的地方是把上面的SQL語句中的AFTER INSERT分別改成AFTER UPDATE和AFTER DELETE便可,以下所示,有興趣的讀者能夠自行測試。
CREATE TRIGGER 產品_Update
ON 產品
AFTER UPDATE
AS
BEGIN
print '有一種產品更改了'
END
GO
CREATE TRIGGER 產品_Delete
ON 產品
AFTER DELETE
AS
BEGIN
print '又刪除了一種產品'
END
GO
11.5.2 測試觸發器功能
建好After Insert觸發器以後,如今來測試一下觸發器是怎麼樣被激活的。
(1)在Management Studio裏新建一個查詢,在彈出的【查詢編輯器】對話框裏輸入如下代碼:
INSERT INTO 產品(產品名稱) VALUES ('大蘋果')
(2)單擊【執行】按鈕,能夠看到【消息】對話框裏顯示出一句提示:「又添加了一種產品」,如圖11.5所示,這說明,After Insert觸發器被激活,並運行成功了。
圖11.5 查看觸發器的運行結果
而若是在【查詢編輯器】裏執行的不是一個Insert語句,而是一個Delete語句的話,After Insert觸發器將不會被激活。如在【查詢編輯器】輸入如下語句:
DELETE FROM 產品 WHERE (產品名稱= '大蘋果')
單擊【執行】按鈕,在【消息】對話框裏只顯示了一句「(1行受影 響)」的提示,而沒有「又添加了一種產品」的提示,如圖11.6所示。這是由於Delete語句是不能激活After Insert觸發器,因此After Insert觸發器裏的「print ‘又添加了一種產品’」語句並無執行。
圖11.6 執行刪除語句不會激活After Insert觸發器
11.5.3 創建觸發器的SQL語句
回顧一下,在Management Studio新建一個觸發器的時候,它在查詢分析對話框給預設了一些SQL代碼,這些代碼其實上就是創建觸發器的語法提示。如今來看一下完整的觸發器語法代碼:
CREATE TRIGGER <Schema_Name, sysname, Schema_Name>.<Trigger_Name, sysname, Trigger_Name>
ON <Schema_Name, sysname, Schema_Name>.<Table_Name, sysname, Table_Name>
AFTER <Data_Modification_Statements, , INSERT,DELETE,UPDATE>
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for trigger here
END
GO
用中文改了一下,以上代碼就一目瞭然了:
CREATE TRIGGER 觸發器名
ON 數據表名或視圖名
AFTER INSERT或DELETE或UPDATE
AS
BEGIN
--這裏是要運行的SQL語句
END
GO
如今再對上面的代碼進行進一步的說明:
l CREATE TRIGGER 觸發器名:這一句聲明SQL語句是用來創建一個觸發器。其中觸發器名在所在的數據庫裏必須是惟一的。因爲觸發器是創建中數據表或視圖中的,因此有不少人都 覺得只要是在不一樣的數據表中,觸發器的名稱就能夠相同,其實觸發器的全名(Server.Database.Owner.TriggerName)是必須 惟一的,這與觸發器在哪一個數據表或視圖無關。
l ON 數據表名或視圖名:這是指定觸發器所在的數據表或視圖,可是請注意,只有Instead Of觸發器才能創建在視圖上。而且,有設置爲With Check Option的視圖也不容許創建Instead Of觸發器。
l AFTER INSERT或 DELETE UPDATE:這是指定觸發器的類型,是After Insert觸發器,仍是After Delete觸發器,或者是After Update觸發器。其中After能夠用For來代取,它們的意思都是同樣的,表明只有在數據表的操做都已正確完成後纔會激活的觸發器。INSERT、 DELETE和UPDATE至少要指定一個,固然也能夠指定多個,若指定多個時,必須用逗號來分開。其順序能夠任意擺放。
l With Encryption:With Encryption是用來加密觸發器的,放在「On 數據表名或視圖名」的後面,「For」的前面。若是使用了這句話,該觸發器將會被加密,任何人都看不到觸發器的內容了。
例一:如下是一個包含提醒電子郵件的觸發器例子,若是訂單表裏記錄有改動的的話(不管增長訂單仍是修改、刪除訂單),則給物流人員張三發送電子郵件:
CREATE TRIGGER 訂單_Insert
ON 訂單
AFTER INSERT, UPDATE, DELETE
AS
EXEC master..xp_sendmail '張三',
'訂單有更改,請查詢肯定'
GO
例二:在訂單明細表裏,折扣字段不能大於0.6,若是插入記錄時,折扣大於0.6的話,回滾操做。
CREATE TRIGGER 訂單明細_Insert
ON 訂單明細
AFTER INSERT
AS
BEGIN
if (Select 折扣 from inserted)>0.6
begin
print '折扣不能大於0.6'
Rollback Transaction
end
END
GO
在示例二中運用了兩個方法,一個是前面說過的,在Inserted表裏查詢某個字段,還有一個是用Rollback Transaction來回滾操做。若是用下面的SQL語句來進行Insert操做的話,插入記錄將會不成功。
INSERT INTO 訂單明細(訂單ID,產品ID,單價,數量,折扣)
VALUES (11077,1,18,1,0.7)
運行結果如圖11.7所示:
圖11.7 插入記錄不符合觸發器裏的約束,則回滾操做
11.6 設置After觸發器的激活順序
對於同一個操做,如Insert、Update或Delete來講,能夠創建多個After Insert觸發器,在11.5.1節中,已經創建了一個名爲「產品_Insert」的觸發器,如今再創建一個After Insert觸發器,做用也是輸出一句有好提示,提示內容爲:「再一次告訴你,你又添加了一種產品」。
CREATE TRIGGER 產品_Insert1
ON 產品
AFTER INSERT
AS
BEGIN
print '再一次告訴你,你又添加了一種產品'
END
GO
從新運行一下插入產品的SQL語句:
INSERT INTO 產品(產品名稱)
VALUES ('大蘋果')
如圖11.8所示,運行一個Insert語句,在【消息】能夠看到一共輸出了兩句話,說明激活兩個不一樣的觸發器。
圖11.8 一個語句激活兩個觸發器
當同一個操做定義的觸發器愈來愈多的時候,觸發器被激活的次序就會 變得愈來愈重要了。在SQL Server 2005裏,用存儲過程【sp_settriggerorder】能夠爲每個操做各指定一個最早執行的After觸發器和最後執行的After觸發器。 sp_settriggerorder語法以下:
sp_settriggerorder [ @triggername = ] '[ triggerschema. ] triggername'
, [ @order = ] 'value'
, [ @stmttype = ] 'statement_type'
[ , [ @namespace = ] { 'DATABASE' | 'SERVER' | NULL } ]
翻譯成中文就是
sp_settriggerorder 觸發器名,
激活次序,
激活觸發器的動做
解釋以下:
l 觸發器名,要用單引號括起來,由於它是一個字符串。
l 激活次序能夠爲First、Last和None:First是指第一個要激活的觸發器;Last是指它最後一個要激活的觸發器;None是不指激活序,由程序任意觸發。
l 激活觸發器的動做能夠是:Insert、Update和Delete。
上面的例子裏,先激活的是【產品_Insert】觸發器,後激活的是【產品_Insert1】觸發器。若是把【產品_Insert1】觸發器設爲First觸發器,把【產品_Insert】觸發器設爲Last觸發器,那麼結果將會徹底不同。設置語句以下:
Exec sp_settriggerorder
'產品_Insert1','First','Insert'
go
Exec sp_settriggerorder
'產品_Insert',’Last’,'Insert'
Go
從新運行一下插入產品的SQL語句:
INSERT INTO 產品(產品名稱)
VALUES ('大蘋果')
運行結果如圖11.9,與圖11.8比較一下,是否是激活次序已經發生變化了?
圖11.9 按次序激活的激活器
在設置After觸發器激活順序時,還有幾點是須要注意的:
l 每一個操做最多隻能設一個First觸發器和一個Last觸發器。
l 若是要取消已經設好的First觸發器或Last觸發器,只要把它們設爲None觸發器便可。
l 若是用Alter命令修改過觸發器內容後,該觸發器會自動變成None觸發器。因此用Alter命令也能夠用來取消已經設好的First觸發器或Last觸發器。
l 只有After觸發器能夠設置激活次序,Instead Of觸發器不能夠設置激活次序。
l 激活觸發器的動做必須和觸發器內部的激活動做一致。舉例說明:After Insert觸發器,只能爲Insert操做設置激活次序,不能爲Delete操做設置激活次序。如下的設置是錯誤的:
Exec sp_settriggerorder
'產品_Insert1','First',’Update’
go
11.7 觸發器的嵌套
當一個觸發器執行時,可以觸活另外一個觸發器,這種狀況就是觸發器的嵌套。在SQL Server 2005裏,觸發器可以嵌套到32層。
若是不想對觸發器進行嵌套的話,能夠經過【容許觸發器激活其餘觸發器】的服務器配置選項來控制。但無論此設置是什麼,均可以嵌套Instead Of觸發器。設置觸發器嵌套的選項更改方法爲:
(1)打開Management Studio,在【對象資源管理】中,右擊服務器名,並選擇【屬性】選項。
(2)單擊【高級】節點。
(3)在【雜項】裏設置【容許觸發器激活其餘觸發器】爲True或False。如圖11.10所示:
圖11.10 開啓/關閉觸發器嵌套
如今,在Northwind數據庫裏建一個操做記錄表,用來記錄全部數據表的操做,不管是對哪一個數據表進行了插入、更新或刪除,均可以把操做內容和操做時間記錄到操做記錄表裏。下面是創建操做記錄表的SQL語句:
CREATE TABLE 操做記錄表(
編號 int IDENTITY(1,1) NOT NULL,
操做表名 varchar(50) NOT NULL,
操做語句 varchar(2000) NOT NULL,
操做內容 varchar(2000) NOT NULL,
操做時間 datetime NOT NULL
CONSTRAINT DF_操做記錄表_操做時間 DEFAULT (getdate()),
CONSTRAINT PK_操做記錄表 PRIMARY KEY CLUSTERED
(
編號 ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
爲了簡便起見,在操做記錄表裏,只建一個After Insert觸發器,觸發器的做用是輸入一條語句:「數據庫又有記錄變更了」。在實際應用時,讀者可自行修改爲所需的代碼。
CREATE TRIGGER 操做記錄表_Insert
ON 操做記錄表
AFTER INSERT
AS
BEGIN
print '數據庫又有記錄變更了'
END
GO
做爲示例,只在類別表裏創建一個After Insert觸發器,當在類別表裏插入一條記錄的時候,該觸發器向操做記錄表裏插入一條記錄,而在操做記錄表裏插入記錄時,將會觸發操做記錄表裏的【操做記錄表_Insert】觸發器。
CREATE TRIGGER 類別_Insert
ON 類別
AFTER INSERT
AS
BEGIN
Declare
@類別名稱 nvarchar(15),
@說明 nvarchar(max)
set @類別名稱= (Select 類別名稱 from inserted)
set @說明= (Select 說明 from inserted)
INSERT INTO 操做記錄表(操做表名,操做語句,操做內容)
VALUES ('類別表','插入記錄','類別名稱:'+@類別名稱+',說明:'+@說明)
END
GO
如今運行一下對類別表的插入語句
INSERT INTO 類別(類別名稱,說明)
VALUES ('書籍','各種圖書')
運行結果如圖11.11所示:
圖11.11 觸發器嵌套被激活
在【消息】對話框能夠看到「數據庫又有記錄變更了」,這說明,觸發器已經被嵌套激活了。若是把【容許觸發器激活其餘觸發器】的選項設爲False,再看看運行結果:
圖11.12 觸發器嵌套沒有被激活
如圖11.12所示,如今沒有「數據庫又有記錄變更了」的提示輸出,說明嵌套的觸發器沒有被激活。
11.8 觸發器的遞歸
觸發器的遞歸是指,一個觸發器從其內部又一次激活該觸發器。例如一 個Insert觸發器的內部還有一條對本數據表插入記錄的SQL語句,那麼這個插入語句就有可能再一次激活這個觸發器自己。固然,這種遞歸的觸發器內部還 會有判斷語句,要必定的狀況下才會執行那個SQL語句,不然的話,就會變成死循環了。
上面的例子說的是直接遞歸的觸發器,還有一種是間接遞歸的觸發器, 舉例說明:當向A表插入一條記錄時,激活了A表的Insert觸發器,A表的Insert觸發器裏有一個SQL語句是對B表進行Insert操做的,而在 B表的Insert觸發器裏也有一句話是對A表進行Insert操做的。這樣就是觸發器的間接遞歸。
通常狀況來講,SQL Server服務器是不容許遞歸的,若是要打開觸發器遞歸的功能,一樣是將【容許觸發器激活其餘觸發器】設爲True,如圖11.10所示。
11.9 設計Instead Of觸發器
Instead Of觸發器與After觸發器的工做流程是不同的。After觸發器是在SQL Server服務器接到執行SQL語句請求以後,先創建臨時的Inserted表和Deleted表,而後實際更改數據,最後才激活觸發器的。而 Instead Of觸發器看起來就簡單多了,在SQL Server服務器接到執行SQL語句請求後,先創建臨時的Inserted表和Deleted表,而後就觸發了Instead Of觸發器,至於那個SQL語句是插入數據、更新數據仍是刪除數據,就一律無論了,把執行權全權交給了Instead Of觸發器,由它去完成以後的操做。
11.9.1 Instead Of觸發器的使用範圍
Instead Of觸發器能夠同時在數據表和視圖中使用,一般在如下幾種狀況下,建議使用Instead Of觸發器:
l 數據庫裏的數據禁止修改:例如電信部門的通話記錄是不能修改的,一旦修改,則通話費用的計數將不正確。在這個時候,就能夠用Instead Of觸發器來跳過Update修改記錄的SQL語句。
l 有可能要回滾修改的SQL語句:如11.5.3節中的例二,用After觸發器並非一個最好的方法,若是用Instead Of觸發器,在判斷折扣大於0.6時,就停止了更新操做,避免在修改數據以後再回滾操做,減小服務器負擔。
l 在視圖中使用觸發器:由於After觸發器不能在視圖中使用,若是想在視圖中使用觸發器,就只能用Instead Of觸發器。
l 用本身的方式去修改數據:如不滿意SQL直接的修改數據的方式,可用Instead Of觸發器來控制數據的修改方式和流程。
11.9.2 設計簡單的Instead Of觸發器
Instead Of觸發器的語法以下:
CREATE TRIGGER 觸發器名
ON 數據表名或視圖名
Instead Of INSERT或DELETE或UPDATE
AS
BEGIN
--這裏是要運行的SQL語句
END
GO
從上面能夠看得出,Instead Of觸發器與After觸發器的語法幾乎一致,只是簡單地把After改成Instead Of。前面說過的11.5.3節中的例二,用After觸發器並非一個最好的方法,若是用Instead Of觸發器,在判斷折扣大於0.6時,就停止了更新操做,避免在修改數據以後再回滾操做,減小服務器負擔。現將原來的觸發器改成Instead Of觸發器:
CREATE TRIGGER 訂單明細_Insert
ON 訂單明細
Instead Of INSERT
AS
BEGIN
SET NOCOUNT ON;
declare
@訂單ID int,
@產品ID int,
@單價 money,
@數量 smallint,
@折扣 real
set @訂單ID = (select 訂單ID from inserted)
set @產品ID = (select 產品ID from inserted)
set @單價 = (select 單價 from inserted)
set @數量 = (select 數量 from inserted)
set @折扣 = (select 折扣 from inserted)
if (@折扣)>0.6
print '折扣不能大
11.10 查看DML觸發器
查看已經設計好的DML觸發器有兩種方式,一種是通用Management Studio來查看,一種是利用系統存儲過程來查看。
11.10.1 在Management Studio中查看觸發器
在Management Studio中查看觸發器的步驟:
(1)啓動Management Studio,登陸到指定的服務器上。
(2)在如圖11.13所示界面的【對象資源管理器】下選擇【數據庫】,定位到要查看觸發器的數據表上,並找到【觸發器】項。
圖11.13 查看觸發器列表
(3)單擊【觸發器】,在右邊的【摘要】對話框裏,能夠看到已經建 好的該數據表的觸發器列表。若是在點擊【觸發器】後,右邊沒有顯示【摘要】對話框,能夠在單擊菜單欄上的【視圖】菜單,選擇【摘要】選項,打開【摘要】對 話框。若是在【摘要】對話框裏沒有看到本應存在的觸發器列表,能夠【摘要】對話框裏右擊空白處,在彈出的快捷菜單中選擇【刷新】選項,刷新對話框後便可看 到觸發器列表。
(4)雙擊要查看的觸發器名,Management Studio自動彈出一個【查詢編輯器】對話框,對話框裏顯示的是該觸發器的內容,如圖11.14所示:
圖11.14 查看觸發器內容
11.10.2 用系統存儲過程查看觸發器
SQL Server 2005裏已經建好了兩個系統存儲過程,能夠用這兩個系統存儲過程來查看觸發器的狀況:
11.10.2.1 sp_help:
系統存儲過程「sp_help」能夠了解如觸發器名稱、類型、建立時間等基本信息,其語法格式爲:
sp_help ‘觸發器名’
舉例:
sp_help '產品_Insert'
運行結果如圖11.15所示,能夠看到觸發器「產品_insert」的基本狀況。
圖11.15 查看觸發器的基本狀況
11.10.2.2 sp_helptext:
系統存儲過程「sp_helptext」能夠查看觸發器的文本信息,其語法格式爲:
sp_helptext ‘觸發器名’
舉例:
sp_helptext '產品_Insert'
運行結果如圖11.16所示,能夠看到觸發器「產品_insert」的具體文本內容。
圖11.16 查看觸發器的基本狀況
於0.6'
else
INSERT INTO 訂單明細
(訂單ID,產品ID,單價,數量,折扣)
VALUES
(@訂單ID,@產品ID,@單價,@數量,@折扣)
END
GO
上面的觸發器裏寫入了一句「SET NOCOUNT ON」,這一句的做用是,屏蔽在觸發器裏Insert語句執行完以後返回的所影響行數的消息。
11.11 修改DML觸發器
在Management Studio中修改觸發器以前,必需要先查看觸發器的內容,經過11.10.1節的第(1)步到第(4)步,細心的讀者能夠已經發現,如圖11.14所 示,在【查詢編輯器】對話框裏顯示的就是用來修改觸發器的代碼。編輯完代碼以後,單擊【執行】按鈕運行便可。修改觸發器的語法以下:
ALTER TRIGGER 觸發器名
ON 數據表名或視圖名
AFTER INSERT或DELETE或UPDATE
AS
BEGIN
--這裏是要運行的SQL語句
END
GO
若是隻要修改觸發器的名稱的話,也可使用存儲過程「sp_rename」。其語法以下:
sp_rename ‘舊觸發器名’,’新觸發器名’
值得一提的是修改觸發器名稱有可能會使某些腳本或存儲過程運行出錯。
11.12 刪除DML觸發器
在Management Studio中刪除觸發器,必需要先查到觸發器列表,經過11.10.1節的第(1)步到第(3)步,能夠查看到數據表下的全部觸發器列表,右擊其中一個 觸發器,在彈出快捷菜單中選擇【刪除】選項,此時將會彈出【刪除對象】對話框,在該對話框中單擊【肯定】按鈕,刪除操做完成。用如下SQL語句也對可刪除 觸發器:
Drop Trigger 觸發器名
注意:若是一個數據表被刪除,那麼SQL Server會自動將與該表相關的觸發器刪除。
11.13 禁用與啓用DML觸發器
禁用觸發器與刪除觸發器不一樣,禁用觸發器時,仍會爲數據表定義該觸發器,只是在執行Insert、Update或Delete語句時,除非從新啓用觸發器,不然不會執行觸發器中的操做。
在Management Studio中禁用或啓用觸發器,也必需要先查到觸發器列表,觸發器列表裏,右擊其中一個觸發器,在彈出快捷菜單中選擇【禁用】選項,便可禁用該觸發器。啓用觸發器與上相似,只是在彈出快捷菜單中選擇【啓用】選項便可。
用如下Alter Table語句也禁用或啓用觸發器,其語法以下:
Alter table 數據表名
Disable或Enable trigger 觸發器名或ALL
用Disable能夠禁用觸發器,用Enable能夠啓用觸發器;若是要禁用或啓用全部觸發器,用「ALL」來代替觸發器名。
11.14 2005新增功能:DDL觸發器
DDL觸發器是SQL Server 2005新增的一個觸發器類型,是一種特殊的觸發器,它在響應數據定義語言(DDL)語句時觸發。通常用於數據庫中執行管理任務。
與DML觸發器同樣,DDL觸發器也是經過事件來激活,並執行其中 的SQL語句的。但與DML觸發器不一樣,DML觸發器是響應Insert、Update或Delete語句而激活的,DDL觸發器是響應Create、 Alter或Drop開頭的語句而激活的。通常來講,在如下幾種狀況下可使用DDL觸發器:
l 數據庫裏的庫架構或數據表架構很重要,不容許被修改。
l 防止數據庫或數據表被誤操做刪除。
l 在修改某個數據表結構的同時修改另外一個數據表的相應的結構。
l 要記錄對數據庫結構操做的事件。
11.15 2005新增功能:設計DDL觸發器
只要注意到DDL觸發器和DML觸發器的區別,設計DDL觸發器與設計DML觸發器也很相似,下面詳細講述一下要怎麼去設計一個DDL觸發器。
11.15.1 創建DDL觸發器的語句
創建DDL觸發器的語法代碼以下:
CREATE TRIGGER trigger_name
ON { ALL SERVER | DATABASE }
[ WITH <ddl_trigger_option> [ ,...n ] ]
{ FOR | AFTER } { event_type | event_group } [ ,...n ]
AS { sql_statement [ ; ] [ ...n ] | EXTERNAL NAME < method specifier > [ ; ] }
用中文取代一下英文能夠看得更明白:
CREATE TRIGGER 觸發器名
ON ALL SERVER或DATABASE
FOR 或AFTER
激活DDL觸發器的事件
AS
要執行的SQL語句
其中:
l ON後面的All Server是將DDL觸發器做用到整個當前的服務器上。若是指定了這個參數,在當前服務器上的任何一個數據庫都能激活該觸發器。
l ON後面的Database是將DDL觸發器做用到當前數據庫,只能在這個數據庫上激活該觸發器。
l For或After是同一個意思,指定的是After觸發器,DDL觸發器不能指定的Stead Of觸發器。
l 激活DDL觸發器的事件包括兩種,在DDL觸發器做用在當前數據庫狀況下可使用如下事件:
CREATE_APPLICATION_ROLE |
ALTER_APPLICATION_ROLE |
DROP_APPLICATION_ROLE |
CREATE_ASSEMBLY |
ALTER_ASSEMBLY |
DROP_ASSEMBLY |
ALTER_AUTHORIZATION _DATABASE |
||
CREATE_CERTIFICATE |
ALTER_CERTIFICATE |
DROP_CERTIFICATE |
CREATE_CONTRACT |
DROP_CONTRACT |
|
GRANT_DATABASE |
DENY_DATABASE |
REVOKE_DATABASE |
CREATE_EVENT_NOTIFICATION |
DROP_EVENT_NOTIFICATION |
|
CREATE_FUNCTION |
ALTER_FUNCTION |
DROP_FUNCTION |
CREATE_INDEX |
ALTER_INDEX |
DROP_INDEX |
CREATE_MESSAGE_TYPE |
ALTER_MESSAGE_TYPE |
DROP_MESSAGE_TYPE |
CREATE_PARTITION_FUNCTION |
ALTER_PARTITION_FUNCTION |
DROP_PARTITION_FUNCTION |
CREATE_PARTITION_SCHEME |
ALTER_PARTITION_SCHEME |
DROP_PARTITION_SCHEME |
CREATE_PROCEDURE |
ALTER_PROCEDURE |
DROP_PROCEDURE |
CREATE_QUEUE |
ALTER_QUEUE |
DROP_QUEUE |
CREATE_REMOTE_SERVICE _BINDING |
ALTER_REMOTE_SERVICE _BINDING |
DROP_REMOTE_SERVICE _BINDING |
CREATE_ROLE |
ALTER_ROLE |
DROP_ROLE |
CREATE_ROUTE |
ALTER_ROUTE |
DROP_ROUTE |
CREATE_SCHEMA |
ALTER_SCHEMA |
DROP_SCHEMA |
CREATE_SERVICE |
ALTER_SERVICE |
DROP_SERVICE |
CREATE_STATISTICS |
DROP_STATISTICS |
UPDATE_STATISTICS |
CREATE_SYNONYM |
DROP_SYNONYM |
CREATE_TABLE |
ALTER_TABLE |
DROP_TABLE |
|
CREATE_TRIGGER |
ALTER_TRIGGER |
DROP_TRIGGER |
CREATE_TYPE |
DROP_TYPE |
|
CREATE_USER |
ALTER_USER |
DROP_USER |
CREATE_VIEW |
ALTER_VIEW |
DROP_VIEW |
CREATE_XML_SCHEMA _COLLECTION |
ALTER_XML_SCHEMA _COLLECTION |
DROP_XML_SCHEMA _COLLECTION |
在DDL觸發器做用在當前服務器狀況下,可使用如下事件:
ALTER_AUTHORIZATION_SERVER |
||
CREATE_DATABASE |
ALTER_DATABASE |
DROP_DATABASE |
CREATE_ENDPOINT |
DROP_ENDPOINT |
|
CREATE_LOGIN |
ALTER_LOGIN |
DROP_LOGIN |
GRANT_SERVER |
DENY_SERVER |
REVOKE_SERVER |
例三,創建一個DDL觸發器,用於保護數據庫中的數據表不被修改,不被刪除。具體操做步驟以下:
(1)啓動Management Studio,登陸到指定的服務器上。
(2)在如圖11.1所示界面的【對象資源管理器】下選擇【數據庫】,定位到【Northwind】數據庫上。
(3)單擊【新建查詢】按鈕,在彈出的【查詢編輯器】的編輯區裏輸入如下代碼:
CREATE TRIGGER 禁止對數據表操做
ON DATABASE
FOR DROP_TABLE, ALTER_TABLE
AS
PRINT '對不起,您不能對數據表進行操做'
ROLLBACK ;
(4)單擊【執行】按鈕,生成觸發器。
例四,創建一個DDL觸發器,用於保護當前SQL Server服務器裏全部數據庫不能被刪除。具體代碼以下:
CREATE TRIGGER 不容許刪除數據庫
ON all server
FOR DROP_DATABASE
AS
PRINT '對不起,您不能刪除數據庫'
ROLLBACK ;
GO
例五,創建一個DDL觸發器,用來記錄數據庫修改狀態。具體操做步驟以下:
(1)創建一個用於記錄數據庫修改狀態的表:
CREATE TABLE 日誌記錄表(
編號 int IDENTITY(1,1) NOT NULL,
事件 varchar(5000) NULL,
所用語句 varchar(5000) NULL,
操做者 varchar(50) NULL,
發生時間 datetime NULL,
CONSTRAINT PK_日誌記錄表 PRIMARY KEY CLUSTERED
(
編號 ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
(2)創建DDL觸發器:
CREATE TRIGGER 記錄日誌
ON DATABASE
FOR DDL_DATABASE_LEVEL_EVENTS
AS
DECLARE @log XML
SET @log = EVENTDATA()
INSERT 日誌記錄表
(事件, 所用語句,操做者, 發生時間)
VALUES
(
@log.value('(/EVENT_INSTANCE/EventType)[1]', 'nvarchar(100)'),
@log.value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'nvarchar(2000)'),
CONVERT(nvarchar(100), CURRENT_USER),
GETDATE()
) ;
GO
其中Eventdata是個數據庫函數,它的做用是以XML格式返回有關服務器或數據庫事件的信息。@log.value是返回log這個XML結點的值,結點的位置是括號裏的第一個參數。
11.15.2 測試觸發器功能
如今測試一下在上一章節中創建好的三個觸發器的功能。下面全部的測試都是在【查詢編輯器】對話框裏進行的,要打開【查詢編輯器】對話框,只要單擊Management Studio裏【新建查詢】按鈕便可。
測試例三:例三是保證【Northwind】數據庫裏不能刪除表和修改表,在【查詢編輯器】對話框裏輸入一個刪除表的SQL語句:
Drop table 操做記錄表
運行結果如圖11.17所示:
圖11.17 不容許刪除表格
測試例四:例四是保證當前服務器裏的全部數據庫不能被刪除,在【查詢編輯器】對話框裏輸入一個刪除數據庫的SQL語句:
Drop DataBase test
運行結果如圖11.18所示:
圖11.18 不容許刪除數據庫
測試例五:例五是記錄對【Northwind】所進行的操做,在【查詢編輯器】對話框裏輸入一條添加數據表和一條刪除數據表的SQL語句,而後再用Select語句查看【目志記錄表】數據表裏全部的記錄:
CREATE TABLE 測試表(
編號int IDENTITY(1,1) NOT NULL,
測試內容varchar(50) NOT NULL)
GO
Drop table 測試表
GO
select * from 日誌記錄表
GO
運行時不要忘了,前面曾經創建過一個不能刪除數據表的觸發器,要先把它禁用或刪除。運行結果如圖11.19所示:
圖11.19 記錄對數據庫的操做
11.16 2005新增功能:查看與修改DDL觸發器
DDL觸發器有兩種,一種是做用在當前SQL Server服務器上的,一種是做用在當前數據庫中的。這兩種DDL觸發器在Management Studio中所在的位置是不一樣的。
l 做用在當前SQL Server服務器上的DDL觸發器所在位置是:【對象資源管理器】,選擇所在SQL Server服務器,定位到【服務器對象】à【觸發器】,在【摘要】對話框裏就能夠看到全部的做用在當前SQL Server服務器上的DDL觸發器。
l 做用在當前數據庫中的DDL觸發器所在位置是:【對象資源管理器】,選擇所在SQL Server服務器,【數據庫】,所在數據庫,定位到【可編程性】à【數據庫觸發器】,在摘要對話框裏就能夠看到全部的當前數據庫中的DDL觸發器。
右擊觸發器,在彈出的快捷菜單中選擇【編寫數據庫觸發器腳本爲】à【CREATE到】à【新查詢編輯器對話框】,而後在新打開的【查詢編輯器】對話框裏能夠看到該觸發器的內容。
在Management Studio若是要修改DDL觸發器內容,就只能先刪除該觸發器,再從新創建一個DDL觸發器。
雖然在Management Studio中沒有直接提供修改DDL觸發器的對話框,但在【查詢編輯器】對話框裏依然能夠用SQL語句來進行修改。下面給出幾個對DDL觸發器操做經常使用 的SQL代碼,因爲對DDL觸發器的操做和對DML觸發器的操做相似,所以再也不詳細說明用法。
l 建立DDL觸發器
CREATE TRIGGER (Transact-SQL)
l 刪除DDL觸發器
DROP TRIGGER (Transact-SQL)
l 修改DDL觸發器
ALTER TRIGGER (Transact-SQL)
l 重命名DDL觸發器
sp_rename (Transact-SQL)
l 禁用DDL觸發器
DISABLE TRIGGER (Transact-SQL)
l 啓用DDL觸發器
ENABLE TRIGGER (Transact-SQL)
l 刪除DDL觸發器
DROP TRIGGER (Transact-SQL)
11.17 觸發器的應用技巧
觸發器的使用範圍很廣,使用的頻率也很高,觸發器的應用技巧也層出不窮,下面介紹一些在觸發器裏經常使用的技巧,但願能夠作到拋磚引玉之功效。
11.17.1 如何知道觸發器修改了多少條記錄
須要注意的是,一種操做類型(Insert、Update或Delete)雖然能夠激活多個觸發器,可是每一個操做類型在一次操做時,對一個觸發器只激活一次。例如,運行一個Update語句,有可能一次更新了十條記錄,可是對於After Update這個觸發器,只激活一次,而不是十次。可是在Inserted表和Deleted表裏會有十條記錄,這個時候,只要利用@@Rowcount這個系統變量就能夠得知更新了多少條記錄。例如:
CREATE TRIGGER 訂單明細刪除_test
ON 訂單明細
AFTER DELETE
AS
BEGIN
print '您這次刪除了' + Cast(@@rowcount as varchar) + '條記錄'
END
GO
Delete FROM 訂單明細 where 折扣=0.25
GO
Delete FROM 訂單明細 where 訂單ID='123456789'
GO
這裏先是創建了一個名爲「訂單明細刪除_test」的觸發器,做用就是顯示刪除了多少條記錄。以後執行兩個SQL語句,一個是刪除折扣爲0.25的記錄,一個是刪除訂單ID號爲123456789的記錄,這條記錄是不存在的。運行結果如圖11.20所示:
圖11.20 顯示刪除的記錄數
在圖11.20能夠看出,用系統變量@@rowcount能夠得到刪除記錄的條數。另外,在圖中還能夠看出,雖然第二個SQL語句刪除的記錄數爲零,可是觸發器仍是被激活了。所以能夠知道,觸發器只與激活它的類型有關,與具體操做的記錄數無關。
11.17.2 如何知道插入記錄的自動編號是多少
在第11.7節,觸發器的嵌套裏,【類別】數據表設計了一個觸發 器,當在【類別】數據表裏插入一件記錄的時候,將會在【操做記錄表】裏也插入一條記錄,用來記錄具體的插入操做的,其實這個觸發器還能夠寫得更好,不但可 以記錄插入操做所用的SQL語句,還能夠記錄下當時插入記錄時候,數據庫爲這個記錄自動生成編號是多少,爲之後的操做提供更大的便利。修改該觸發器的代碼 以下:
ALTER TRIGGER 類別_Insert
ON 類別
AFTER INSERT
AS
BEGIN
Declare
@類別名稱 nvarchar(15),
@說明 nvarchar(max)
set @類別名稱 = (Select 類別名稱 from inserted)
set @說明 = (Select 說明 from inserted)
INSERT INTO 操做記錄表 (操做表名,操做語句,操做內容)
VALUES ('類別表','插入記錄',
'插入了ID號爲'+cast(@@IDENTITY as varchar)+'的記錄:類別名稱:'
+@類別名稱+',說明:'+@說明)
END
GO
從上面的代碼能夠看出,用@@IDENTITY能夠得到剛插入記錄的標識值,在本例中是它的主鍵值。插入記錄後,在【操做記錄表】裏能夠詳細查看到插入的記錄的編號以及它的內容。
11.17.3 如何知道某個字段是否被修改
在Update觸發器和Insert觸發器裏,能夠用「Update(字段名)」來判斷某個字段是否是被更改,返回的是一個布爾值。例如定單生成後,只能修改折扣的觸發器:
CREATE TRIGGER 只容許修改折扣
ON 訂單明細
Instead Of UPDATE
AS
BEGIN
SET NOCOUNT ON;
if update(折扣)
begin
declare
@訂單ID int,
@產品ID int,
@折扣 real
set @訂單ID = (select 訂單ID from inserted)
set @產品ID = (select 產品ID from inserted)
set @折扣 = (select 折扣 from inserted)
update 訂單明細 set 折扣=@折扣
where 訂單ID=@訂單ID and 產品ID=@產品ID
end
else
begin
print '只能更改折扣字段'
end
END
GO
update 訂單明細 set 折扣=0.2
where 訂單ID=10288 and 產品ID=54
Go
update 訂單明細 set 訂單ID=10288
where 訂單ID=10288 and 產品ID=54
Go
上面的代碼,先創建了一個觸發器,只有修改了折扣字段的Update語句纔會被執行。而後寫了兩個Update的SQL語句,一個是修改了折扣字段的,一個是沒有修改折扣字段的。運行後的結果如圖11.21所示。第一個SQL語句被正確執行,第二個SQL語句沒有被執行。
圖11.21 用Update判斷字段是否被修改
11.17.4 如何返回錯誤信息
雖然上面介紹觸發器時,用過不少次Print來輸出自定義的信息,可是實際上,只有在用【查詢編輯器】中運行SQL語句才能看獲得這些自定義的信息,而其餘的前端應用程序都不會顯示出這些自定義的信息,包括用Management Studio也同樣。
讀者能夠自行測試一下,在Management Studio裏打開【訂單明細】數據表,由於上面建了一個【只容許修改折扣】的觸發器,因此只要在不是折扣的字段裏修改數據後,再將鼠標聚焦到其餘記錄上 時,被修改的數據立刻就會回滾到修改前的狀態,在這個過程當中,幾乎是看不到什麼提示的。若是想要在這個過程當中看到提示的話,就要將觸發器修改一下,加上 「Raiserror」語句,具體修改代碼以下:
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
ALTER TRIGGER 只容許修改折扣
ON 訂單明細
Instead Of UPDATE
AS
BEGIN
SET NOCOUNT ON;
if update(折扣)
begin
declare
@訂單ID int,
@產品ID int,
@折扣 real
set @訂單ID = (select 訂單ID from inserted)
set @產品ID = (select 產品ID from inserted)
set @折扣 = (select 折扣 from inserted)
update 訂單明細set 折扣=@折扣
where 訂單ID=@訂單ID and 產品ID=@產品ID
end
else
begin
print '只能更改折扣字段'
Raiserror('除了折扣字段以外的其餘字段信息不能修改',16,5)
end
END
修改完觸發器以後,再去修改其餘非「折扣」字段的內容時,就會彈出錯誤提示,如圖11.22所示,Raiserror的用法能夠查看SQL Server 2005的幫助。
圖11.22 顯示錯誤信息
11.18 小結
觸發器是與數據庫和數據表相結合的特殊的存儲過程,當數據表有Insert、Update、Delete操做或數據庫有Create、Alter、Drop操做的時候,能夠激活觸發器,並運行其中的T-SQL語句。
在SQL Server 2005中觸發器分爲DML觸發器和DDL觸發器兩種。其中DML觸發器又分爲After觸發器和Instead Of觸發器兩種。After觸發器是先修改記錄後激活的觸發器;Instead Of觸發器是「取代」觸發器。DDL觸發器根據做用範圍能夠分爲做用在數據庫的觸發器和做用在服務器的觸發器兩種。After觸發器只能用於數據表中,而Instead Of觸發器便可以用在數據表中,也能夠用在視圖中。
使用CREATE TRIGGER語句能夠建立觸發器,使用ALTER TRIGGER語句能夠修改觸發器,使用Drop Trigger語句能夠刪除觸發器。觸發器容許嵌套和遞歸,嵌套最多能夠是32層。