zoukankan      html  css  js  c++  java
  • 今天说一下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 触发器,发现执行顺序也是 这样纸。

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

  • 相关阅读:
    url传递参数带 + ,解决办法
    操作系统——内存地址重定位
    算法——二分查找变形题
    Java——代码性能优化
    maven——添加插件和添加依赖有什么区别?
    JavaWeb——Servlet如何调用线程池中的线程?
    「ZJOI2016」小星星
    [十二省联考2019]字符串问题
    [十二省联考2019]春节十二响
    [十二省联考2019]异或粽子
  • 原文地址:https://www.cnblogs.com/Gin-23333/p/5244464.html
Copyright © 2011-2022 走看看