2008-09-18 47 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