我有一个由外部CRM部分创建和编辑的数据库,其中某些表上有多个(最多2个)后触发器。这是由于1个触发器是由CRM自动生成的(我对其控制有限),另一个包含我的代码。
CRM触发器为插入的数据行生成主键。我的触发器需要访问该主键,以便将其作为外键写入另一个表。我使用
Select @id=max(id) from mytable
因为Scope_Identity没有以某种方式产生期望的结果。
这一直有效,直到我让CRM重新创建表和它自己的触发器。触发器选择的该表的最大id似乎总是actual_id-1。
当我使用相同的代码更改触发器时,它总是让程序重新运行。
我的问题是:SQL server(我使用的是SQL server 2008)是否按创建时间设置其触发顺序?
以及:是否
sp_settriggerorder @triggername='mycustomtrigger', @order='Last', @stmttype='INSERT'
要永久更改这个,还是每次CRM重新创建其触发器时,我都必须再次调用该过程?(使用DROP和CREATE,而不是ALTER)
希望这个问题的答案能帮助到同样问题的人。
问候
它没有文档,但我相信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 server(我使用的是SQL server 2008)是否按创建时间设置其触发顺序?
它也出现在,但我不会依赖它。sp_settriggerorder
是唯一记录任何订单的地方。
最后,正如我在评论中提到的,我不会依赖您当前的Select @id=max(id) from mytable
方法-它可能会因多种原因而被破坏,但最重要的是,每个方法触发一次触发器,并且可能会响应多个行而触发,因此您应该编写触发器来使用inserted
伪表(并期望它包含0、1或多行)。