因为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 触发器,发现执行顺序也是 这样纸。

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

今天说一下DML触发器的顺序的更多相关文章

  1. sp_settriggerorder 设置触发器执行顺序

    sp_settriggerorder (Transact-SQL)     本主题适用于:SQL Server(从 2008 开始)Azure SQL 数据库Azure SQL 数据仓库并行数据仓库 ...

  2. SQL Server 数据库DML触发器 【一】

    今天学习SQL Server数据库中DML触发器(DDL触发器以后有时间继续学习). 当删除一条创建有触发器的表中的内容时,触发器执行SQL语句. 1.首相先创建一张表,表名称是 [Test] , 内 ...

  3. 杂谈--DML触发器学习

    触发器按类型分为三类: 1. DML 触发器,在数据变更时触发: 2. DDL 触发器,在修改数据库级别或实例级别对象时触发: 3. Login 触发器,在用户登录时触发: 最常见的是DML触发器,D ...

  4. DML触发器1

    数据库触发器是特殊的存储程序.通常不直接调用它们,而是由数据库的事件触发. 触发器分类: >DML触发器 >instead-of触发器 >系统事件触发器,还可以是DDL 一. DML ...

  5. [转]Oracle Form 触发器执行顺序

    Trigger 不是数据库中的触发器,不过功能类似,都是当某个事件发生的时候会触发. Trigger中可以编写代码,当对应事件发生的时候就会执行该Trigger中的代码. Oracle Form中的T ...

  6. FORM触发器执行顺序

    触发器执行顺序: 1. 当打开FORM时: (1) PRE-FORM (2) PRE-BLOCK(BLOCK级) (3) WHEN-NEW-FORM-INSTANCE (4) WHEN-NEW-BLO ...

  7. SQL语句(二十一)—— 触发器(DML触发器)

    触发器 一 .触发器概述(特殊的存储过程) 定义: 在修改指定表值的数据时执行的 存储过程. 不同的是 : 执行存储过程要使用EXEC语句来调用,而触发器的执行不需要使用EXEC语句来调用. 作用: ...

  8. 触发器三(行级DML触发器)(学习笔记)

    行级DML触发器 每当一条记录出现更新操作时进行触发操作定义时要定义FOR EACH ROW 使用":old.字段"和":new.字段"标识符 No. 触发语句 ...

  9. 触发器二(DML触发器)(学习笔记)

    DML触发器(语句触发器) 由DML语句进行触发,当用户执行了INSERT,UPDATE,DELETE操作时就会触发操作 示例一.只有在每个月的10日才允许办理,新员工入职与离职,其他时间不允许增加和 ...

随机推荐

  1. 两台Linux主机之间文件的复制

    使用scp命令可以实现两台Linux主机之间的文件复制,基本格式是: scp [可选参数] file_source file_target 1. 复制文件 命令格式: scp local_file r ...

  2. Malformed \uxxxx encoding解决方法

    java.lang.IllegalArgumentException: Malformed \uxxxx encoding. at java.util.Properties.loadConvert(U ...

  3. ActionContext和ServletActionContext区别

    1. ActionContext 在Struts2开发中,除了将请求参数自动设置到Action的字段中,我们往往也需要在Action里直接获取请求(Request)或会话(Session)的一些信息, ...

  4. DCloud与APICloud的对比

    DCloud与APICloud这两家目前应该说是市场占有率和人气较高的国内团队:国内还有一些其他的方案如AppCan.exMobi之类的,但可能是商业运作手法上Big不够,近两年的名气不太大,但各自其 ...

  5. Netbeans 8.0.2 For PHP继续坑

    仍然没有修复PHP好用的代码快速导航功能,坑!

  6. node.js图片上传

    1.node-formidable 对文件上传提供帮助的组件 2.app.js var formidable = require('formidable'); var http = require( ...

  7. SQL Server代码如何快速格式化

    在SQL Server中我们经常需要编写各种SQL脚本,例如存储过程和函数等,由于在编写过程中,经常会进行调整,有些关键字我们用的大写,有的我们用的小写,有的后面结束用:分割有的又没有.对于有强迫症的 ...

  8. Converse.js – 开源的 XMPP 聊天客户端

    Converse.js 是一个运行在浏览器的免费和开源的聊天客户端.它可以集成到任何网页.类似于 Facebook 的聊天,它也支持多用户聊天室.Converse.js 可以连接到任何可访问的 XMP ...

  9. Asp.net Ibatis 增、删、改、查

    好久都没用.net Ibatis配置了 今天给大家分享一下获取它的增.删.改.查. #region 节点类型表 public bool InsertNodeType(NodeType allRevie ...

  10. WPF中的Invoke

    今天帮同事看一个问题,她用为了实现动画效果用主线程执行Thread.Sleep,然后界面就卡死了. 这个问题好解决,new 一个Thread就行了,但是更新WPF的界面需要主线程的操作,然后习惯性的打 ...