Sqlserver标准触发顺序

时间:2012-09-07 08:23:10

标签: sql-server-2008 triggers crm

我有一个由外部CRM部分创建和编辑的数据库,其中某些表具有多个(最多2个)后触发器。这是由于1个触发器由CRM自动生成(我对其进行了有限的控制),另一个触发器包含我的代码。

CRM触发器为插入的数据行生成主键。我的触发器需要访问该主键,以便将其作为外键写入另一个表。我用

Select @id=max(id) from mytable

因为Scope_Identity不能以某种方式产生预期的结果。

这一直有效,直到我让CRM重新创建表格及其自己的触发器。我的触发器选择的该表的最大ID似乎始终为 actual_id - 1

当我使用相同的代码更改我的触发器时,它总是让程序再次运行。

我的问题是: SQL服务器(我使用的是SQL Server 2008)是否按创建时间设置了触发顺序?

和: 是

sp_settriggerorder @triggername='mycustomtrigger', @order='Last', @stmttype='INSERT'

每次CRM重新创建触发器时,是否会永久更改此值,还是必须再次调用该过程? (使用DROP和CREATE,而不是ALTER)

希望这些答案可以帮助有人看到同样的问题。

此致

1 个答案:

答案 0 :(得分:2)

它不是记录,但我相信LAST设置将保留触发器,前提是它未被修改。 (相反, 记录了如果修改了触发器将失去此设置)。但是,它似乎有效:

create table T (ID int not null)
go
create trigger T_T1 on T
after insert
as
    RAISERROR('T1',10,1) WITH NOWAIT
go
create trigger T_T2 on T
after insert
as
    RAISERROR('T2',10,1) WITH NOWAIT
go
create trigger T_T3 on T
after insert
as
    RAISERROR('T3',10,1) WITH NOWAIT
go
insert into T(ID) values (1)
go
sp_settriggerorder 'T_T2','Last','INSERT'
go
insert into T(ID) values (2)
go
drop trigger T_T1
go
create trigger T_T1 on T
after insert
as
    RAISERROR('T1',10,1) WITH NOWAIT
go
insert into T(ID) values (3)

结果:

T1
T2
T3

(1 row(s) affected)
T1
T3
T2

(1 row(s) affected)
T3
T1
T2

(1 row(s) affected)

关于你的第一个问题:

  

SQL服务器(我使用的是SQL Server 2008)是否按创建时间设置了触发顺序?

它也出现,但我不会依赖它。 sp_settriggerorder是唯一记录任何排序的地方。

最后,正如我的评论中所提到的,我不会依赖于您当前的Select @id=max(id) from mytable方法 - 它可能会因为多种原因而被破坏,但最重要的是每个方法触发一次触发器,并且可能会响应多个行而触发,因此您应该编写触发器以使用inserted伪表(并期望它包含0行,1行或多行)。