SQL Server 2005 學習筆記之觸發器簡介

 觸發器實際上就是一種特殊類型的存儲過程,其特殊性表現在:它是在執行某些特定的T-SQL語句時自動的。

11.1  觸發器簡介

觸發器實際上就是一種特殊類型的存儲過程,它是在執行某些特定的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  完成比約束更復雜的數據約束:觸發器可以實現比約束更爲複雜的數據約束

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層。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章