今天说一下DML触发器的顺序

因为05之后的版本允许了一个对象有多个after触发器,所以呢~顺序方面还是要留意一下下的。比如我现在要往一个测试表里面添加多个触发器。

USE Test
GO 
CREATE TABLE AAA3 (ID INT IDENTITY(1,1),Name NVARCHAR(50))
GO

CREATE TRIGGER TR_AAA3_1 ON AAA3 FOR INSERT
AS
BEGIN 
    PRINT 'TRIGGER1'
END
GO 

CREATE TRIGGER TR_AAA3_2 ON AAA3 FOR INSERT
AS
BEGIN 
    PRINT 'TRIGGER2'
END
GO 

CREATE TRIGGER TR_AAA3_3 ON AAA3 FOR INSERT
AS
BEGIN 
    PRINT 'TRIGGER3'
END
GO 

CREATE TRIGGER TR_AAA3_4 ON AAA3 FOR INSERT
AS
BEGIN 
    PRINT 'TRIGGER4'
END
GO 

CREATE TRIGGER TR_AAA3_5 ON AAA3 FOR INSERT
AS
BEGIN 
    PRINT 'TRIGGER5'
END
GO 

CREATE TRIGGER TR_AAA3_6 ON AAA3 FOR INSERT
AS
BEGIN 
    PRINT 'TRIGGER6'
END
GO 

CREATE TRIGGER TR_AAA3_7 ON AAA3 FOR INSERT
AS
BEGIN 
    PRINT 'TRIGGER7'
END
GO 

CREATE TRIGGER TR_AAA3_8 ON AAA3 FOR INSERT
AS
BEGIN 
    PRINT 'TRIGGER8'
END
GO 
创建测试表和触发器

 

然后添加几条测试数据来看顺序

INSERT INTO dbo.AAA3
        ( Name )
VALUES  ( N'a' )

GO 2

开始执行循环
TRIGGER1
TRIGGER2
TRIGGER3
TRIGGER4
TRIGGER5
TRIGGER6
TRIGGER7
TRIGGER8

(1 行受影响)
TRIGGER1
TRIGGER2
TRIGGER3
TRIGGER4
TRIGGER5
TRIGGER6
TRIGGER7
TRIGGER8
测试数据

 

可以看到是按照创建顺序来执行的。(官方提出表里面的各个触发器执行的顺序其实是无序的。只有在如果了第一条和最后一条执行触发器之后,才能保证这2个触发器的顺序,然而其它的触发器执行的顺序是无须的。)

然后我试下指定第一条和最后一条的位置。然后再进行测试。(是指定了触发器7第一,触发器4最后一个)。其它顺序也没变。

EXEC sys.sp_settriggerorder @triggername = N'TR_AAA3_7', -- nvarchar(517)
    @order = 'first', -- varchar(10)
    @stmttype = 'INSERT', -- varchar(50)
    @namespace = NULL -- varchar(10)

EXEC sys.sp_settriggerorder @triggername = N'TR_AAA3_4', -- nvarchar(517)
    @order = 'last', -- varchar(10)
    @stmttype = 'INSERT', -- varchar(50)
    @namespace = NULL -- varchar(10)

INSERT INTO dbo.AAA3
        ( Name )
VALUES  ( N'a' )

GO 2

开始执行循环
TRIGGER7
TRIGGER1
TRIGGER2
TRIGGER3
TRIGGER5
TRIGGER6
TRIGGER8
TRIGGER4

(1 行受影响)
TRIGGER7
TRIGGER1
TRIGGER2
TRIGGER3
TRIGGER5
TRIGGER6
TRIGGER8
TRIGGER4
重新测试

看起来好像也不是无序啊~就和创建时间排序一致嘛~但是我认为还是不要抱这种错觉,这个版本是这样,没人能保证下一个版本还是这样哦!所以我觉得还是不要太相信这个特意做出来的测试例子。

如果需要查询触发器的状态。可以参考以下语句

SELECT a.name,a.object_id,a.is_disabled,a.is_instead_of_trigger,b.is_first,b.is_last,b.is_trigger_event FROM sys.triggers a
    INNER JOIN sys.trigger_events b ON a.object_id = b.object_id
    WHERE parent_id = OBJECT_ID('AAA3')

name                                                                                                                             object_id   is_disabled is_instead_of_trigger is_first is_last is_trigger_event
-------------------------------------------------------------------------------------------------------------------------------- ----------- ----------- --------------------- -------- ------- ----------------
TR_AAA3_1                                                                                                                        775673811   0           0                     0        0       1
TR_AAA3_2                                                                                                                        791673868   0           0                     0        0       1
TR_AAA3_3                                                                                                                        807673925   0           0                     0        0       1
TR_AAA3_4                                                                                                                        823673982   0           0                     0        1       1
TR_AAA3_5                                                                                                                        839674039   0           0                     0        0       1
TR_AAA3_6                                                                                                                        855674096   0           0                     0        0       1
TR_AAA3_7                                                                                                                        871674153   0           0                     1        0       1
TR_AAA3_8                                                                                                                        887674210   0           0                     0        0       1

 

最后我们乱入一个InsteatOf 触发器。看下执行顺序是怎么样。

CREATE TRIGGER TR_AAA3_1_1 ON AAA3 INSTEAD OF INSERT
AS
BEGIN 
    INSERT INTO dbo.AAA3
            (  Name )
    SELECT Inserted.Name
        FROM Inserted
    PRINT 'Instead 1'
END
GO 


INSERT INTO dbo.AAA3
        ( Name )
VALUES  ( N'a' )

TRIGGER7
TRIGGER1
TRIGGER2
TRIGGER3
TRIGGER5
TRIGGER6
TRIGGER8
TRIGGER4

(1 行受影响)
Instead 1

TRIGGER7
TRIGGER1
TRIGGER2
TRIGGER3
TRIGGER5
TRIGGER6
TRIGGER8
TRIGGER4

(1 行受影响)
Instead 1
测试instead of 触发器

 

就是说instead of 触发器执行是会在 after触发器之后??我怀疑是因为创建时间问题。然后反过来先创建 instead of 触发器,发现执行顺序也是 这样纸。

恕我眼拙,在触发器介绍的文档里面也没有找到这个描述。还是各位不吝赐教

 

posted on 2016-03-05 11:43  神崎橙  阅读(411)  评论(0编辑  收藏  举报

导航