2008-09-18 48 views
25

有誰知道SQL Server如何確定順序觸發器(相同類型,即觸發器之前)執行。有什麼方法可以改變這個,以便我可以指定我想要的順序。如果沒有,爲什麼不。SQL Server觸發器 - 執行順序

謝謝。

回答

2

訂單由sql server設置,您可以做的唯一的事情就是使用系統sp(sp_settriggerorder)來設置哪個觸發器會首先觸發,哪個觸發器會最後觸發。

除了設置要觸發的第一個和最後一個觸發器之外,您不能修改或判斷sql server將使用哪個順序。因此,您需要構建觸發器,以便它們不依賴於它們被觸發的順序。即使你確定今天的命令,它明天可能會改變。

此信息基於Sql Server 2000,但我不認爲2005/2008在這方面的行爲不同。

4

使用sp_Settriggerorder存儲過程,可以定義觸發器的執行順序。

sp_settriggerorder [ @triggername = ] ‘[ triggerschema. ] triggername’ 
, [ @order = ] ‘value’ 
, [ @stmttype = ] ’statement_type’ 
[ , [ @namespace = ] { ‘DATABASE’ | ‘SERVER’ | NULL } ] 

第二個參數「order」可以取三個值,這意味着它可以考慮最多三個觸發器。

  1. 首先 - 觸發首先被燒成
  2. 最後 - 激活觸發器最後
  3. 無 - 觸發以隨機順序發射。
1

使用此係統存儲過程:

sp_settriggerorder[@triggername = ] 'triggername', [@order = ] 'value', [@stmttype = ] 'statement_type' 
5

sp_settriggerorder僅適用於AFTER觸發器。

4

您可以確保首先觸發哪個觸發器,哪個觸發器最後觸發,哪些觸發器使用sp_settriggerorder在中間觸發。如果您需要同步三個以上,它不會出現在SQL Server 2005中。

這是一個取自here的示例(鏈接的文章有更多信息)。

sp_settriggerorder [ @triggername = ] ‘[ triggerschema. ] triggername’ 
, [ @order = ] ‘value’ 
, [ @stmttype = ] ’statement_type’ 
[ , [ @namespace = ] { ‘DATABASE’ | ‘SERVER’ | NULL } ] 
10

如果你在擔心觸發訂單,那麼你真的應該採取一種倒退,並考慮你正在嘗試做的,如果有這樣做的更好的辦法的地步。事實上,這不是一件容易改變的事情,應該告訴你一些事情。

觸發器總是看起來像一個真正整潔的解決方案,並在正確的地方,他們是非常寶貴的,價格高,它真的很容易與他們創造的調試噩夢。過去我失去了許多小時,試圖調試一些模糊的數據庫行爲,只是爲了找到原因被忽略的觸發器。

17

使用SetTriggerOrder是好的,但如果你的代碼依賴於執行的特定序列,爲什麼不是所有的觸發器包裝到存儲過程,並有第一個撥打第二個,第二個叫第三等

然後你只需要在觸發器中執行第一個。

有人將來會很感激他們不需要在系統表中挖掘來確定自定義執行順序。

+7

通常我們不這樣做,因爲我們無法輕鬆訪問存儲過程中的插入和刪除僞指令。 – mwigdahl 2012-06-27 13:57:52

14

您可以使用sp_settriggerorder來定義表上每個觸發器的順序。

但是,我會爭辯說,有一個觸發器可以處理多種事情,會更好。這是,特別是所以如果順序很重要,因爲如果你有多個觸發器,那麼重要性就不會很明顯。想象一下,有人試圖在賽道上支持數據庫月/年。當然,可能會出現這種情況,你需要有多個觸發器,或者它確實是更好的設計,但我會開始假設你應該有一個並從那裏開始工作。

1

這方面的一個百萬美元的說法 -

sp_settriggerorder:指定在第一 或上次解僱的AFTER觸發器的。在第一個和最後一個觸發器之間觸發的AFTER觸發器以未定義的順序執行。

來源:MSDN

2

使用:

例如:

USE AdventureWorks; 
GO 
EXEC sys.sp_settriggerorder @triggername = N'', -- nvarchar(517) 
    @order = '', -- varchar(10) 
    @stmttype = '', -- varchar(50) 
    @namespace = '' -- varchar(10) 

第一和最後一個觸發器必須是兩個不同的觸發器。

第一:首先觸發觸發器。

最後:觸發器最後被觸發。

無:觸發器以未定義的順序觸發。

和看@stmttype此鏈接的價值:爲@namespace = { '數據庫' DDL Events

而且| 'SERVER'| NULL}以及更多信息,請參閱:DDL Triggers