一個表上的多個觸發器執行順序問題

一、觸發器基礎 

1、觸發器使用  
     可以定義一個無論何時用insert語句向表中插入數據時都會執行的觸發器。    
     當觸發insert觸發器時,新的數據行就會被插入到觸發器表和inserted表中。inserted表是一個邏輯表,它包含了已經插入的數據行的一個副本。inserted表包含了insert語句中已記錄的插入動作。inserted表還允許引用由初始化insert語句而產生的日誌數據。觸發器通過檢查inserted表來確定是否執行觸發器動作或如何執行它。inserted表中的行總是觸發器表中一行或多行的副本。    
    日誌記錄了所有修改數據的動作(insert、update和delete語句),但在事務日誌中的信息是不可讀的。然而,inserted表允許你引用由insert語句引起的日誌變化,這樣就可以將插入數據與發生的變化進行比較,來驗證它們或採取進一步的動作。也可以直接引用插入的數據,而不必將它們存儲到變量中。   
    
2、delete觸發器的工作過程    
     當觸發delete觸發器後,從受影響的表中刪除的行將被放置到一個特殊的deleted表中。deleted表是一個邏輯表,它保留已被刪除數據行的一個副本。deleted表還允許引用由初始化delete語句產生的日誌數據。     
使用delete觸發器時,需要考慮以下的事項和原則:     
(1)、當某行被添加到deleted表中時,它就不再存在於數據庫表中;因此,deleted表和數據庫表沒有相同的行。    
(2)、創建deleted表時,空間是從內存中分配的。deleted表總是被存儲在高速緩存中。     
(3)、爲delete動作定義的觸發器並不執行truncate   table語句,原因在於日誌不記錄truncate   table語句。    
   
   
3、instead   of觸發器的工作過程    
     可以在表或視圖上指定instead   of觸發器。執行這種觸發器就能夠替代原始的觸發動作。instead   of觸發器擴展了視圖更新的類型。對於每一種觸發動作(insert、update或   delete),每一個表或視圖只能有一個instead   of觸發器。    
     instead   of觸發器被用於更新那些沒有辦法通過正常方式更新的視圖。例如,通常不能在一個基於連接的視圖上進行delete操作。然而,可以編寫一個instead   of   delete觸發器來實現刪除。上述觸發器可以訪問那些如果視圖是一個真正的表時已經被刪除的數據行。將被刪除的行存儲在一個名爲deleted的工作表中,就像after觸發器一樣。相似地,在update  instead   of觸發器或者insert   instead   of觸發器中,你可以訪問inserted表中的新行。    
     不能在帶有with   check   option定義的視圖中創建instead   of觸發器。    
   
   
 4、update觸發器的工作過程    
      可將update語句看成兩步操作:即捕獲數據前像(before   image)的delete語句,和捕獲數據後像(after   image)的insert語句。當在定義有觸發器的表上執行update語句時,原始行(前像)被移入到deleted表,更新行(後像)被移入到inserted表。    
      觸發器檢查deleted表和inserted表以及被更新的表,來確定是否更新了多行以及如何執行觸發器動作。    
      可以使用if   update語句定義一個監視指定列的數據更新的觸發器。這樣,就可以讓觸發器容易的隔離出特定列的活動。當它檢測到指定列已經更新時,觸發器就會進一步執行適當的動作,例如發出錯誤信息指出該列不能更新,或者根據新的更新的列值執行一系列的動作語句。  

二、觸發器執行順序

 1、典型問題描述: 有多個觸發器tg1,tg2,tg3,都是update觸發,系統是按照名稱排序tg1->tg2->tg3的順序觸發,還是同時觸發? 

2、指定第一個和最後一個觸發器  
     可將與表相關聯的after 觸發器之一指定爲每個 insert、delete和update 觸發動作執行的第一個或最後一個after 觸發器。在第一個和最後一個觸發器之間激發的after觸發器將按未定義的順序執行。   
     若要指定   after   觸發器的順序,請使用   sp_settriggerorder   存儲過程。可用的選項有:     
     

     第一個     
  指定該觸發器是爲觸發操作激發的第一個   after   觸發器。  
   
  最後一個    
  指定該觸發器是爲觸發操作激發的最後一個   after   觸發器。  
   
  無    
  指定觸發器的激發沒有特定的順序。主要用於重新設置第一個或最後一個觸發器。  
   
  以下是使用   sp_settriggerorder   的示例:  
   
  sp_settriggerorder   @triggername   =   'mytrigger',   @order   =   'first',   @stmttype   =   'update'  
   
   

  注意: 第一個和最後一個觸發器必須是兩個不同的觸發器。  
   
 3、可能同時在表上定義了insert、update 和delete觸發器。每種語句類型可能都有自己的第一個和最後一個觸發器,但它們不能是相同的觸發器。  
   
  如果爲某個表定義的第一個或最後一個觸發器不包括觸發操作,如 for   update、for  delete 或for insert,則缺少的操作將沒有第一個或最後一個觸發器。  
   
  不能將   instead   of 觸發器指定爲第一個或最後一個觸發器。在對基礎表進行更新前激發instead   of 觸發器。然而,如果由   instead   of   觸發器對基礎表進行更新,則這些更新將發生於在表上定義觸發器(包括第一個觸發器)之後。例如,如果視圖上的   instead   of   觸發器更新基表並且該基表包含三個觸發器,則該三個觸發器在   instead   of   觸發器插入數據之前激發。有關更多信息,請參見指定觸發器何時激發。  
   
  如果alter trigger  語句更改了第一個或最後一個觸發器,則將除去 first   或 last 特性,並且順序值將設置爲 none;必須用   sp_settriggerorder   重置此順序。    
  objectproperty   函數使用屬性   execisfirsttrigger   和   execislasttrigger   報告觸發器的順序是第一個還是最後一個。  
   
  複製將爲本身是即時更新訂戶或排隊更新訂戶的任何表自動生成第一個觸發器。複製要求它的觸發器是第一個觸發器。如果嘗試使具有第一個觸發器的表成爲即時更新訂戶或排隊更新訂戶,複製將引發錯誤。如果使表成爲即時更新訂戶或排隊更新訂戶之後使用戶定義觸發器成爲第一個觸發器,則sp_settriggerorder 會返回一個錯誤。如果在複製觸發器上使用 alter,或使用   sp_settriggerorder   將複製觸發器更改爲最後觸發器或無觸發器,則訂閱將不能正確工作。  

兩個觸發器完全相同嗎,如果全部相同,會先執行後建立的觸發器。執行的順序與建立的順序相反。
(原文地址:http://www.cnblogs.com/netguid/archive/2007/03/29/692241.aspx)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章