atitit...触发器机制 ltrigger mechanism sumup .的总结O8f

atitit...触发器机制  ltrigger  mechanism sumup .的总结O8f

 

1. 触发器的类型 1

2. 实现原理 1

3. After触发器 Vs Instead Of触发器 1

4. DML 触发器 Vs DDL 触发器 3

5. 触发器and事务 3

6. 下面描述三种常见触发器中事务的情况: 5

7. 2、 instead of 触发器 (之前触发) 7

8. 触发器有两个特殊的表:插入表(instered表)和删除表(deleted表)。 7

9. 表格记录复制and迁移SELECT INTO 和 INSERT INTO SELECT 8

10. 参考 9

 

1. 触发器的类型

· DML触发器(DML Triggers) 

· DDL触发器(DDL Triggers) 

· 事务模式(Transaction modes) 

· 显式事务(Explicit Transactions) 

· 自动提交事务(Autocommit Transactions) 

· 隐式事务(Implicit Transactions) 

· 批范围的事务(Batch-scoped Transactions) 

2. 实现原理

3. After触发器 Vs Instead Of触发器 

            After 触发器将在处理触发操作(InsertUpdate 或 Delete)、Instead Of 触发器和约束之后激发。Instead Of是将在处理约束前激发,以替代触发操作。下面两张图描述了After触发器和Instead Of触发器的执行先后顺序。

 

 

作者::老哇的爪子Attilax艾龙,EMAIL:1466519819@qq.com

转载请注明来源: http://blog.csdn.net/attilax

 

             

     图1                                                                             图2

4. DML 触发器 Vs DDL 触发器

      DML 触发器在 InsertUpdate 和 Delete 语句上操作,可以作为After 触发器 和 Instead Of 触发器。

     DDL 触发器对 Create、Alter、Drop 和其他 DDL 语句以及执行 DDL 式操作的存储过程执行操作,只可作为After触发器,不能Instead Of触发器。

     前面的内容,有描述DML触发器中的After & Instead Of触发器内容,下面直接来看DDL的操作顺序:

     

     图3.

     从图3.可以知道,在DDL触发器中,是没有创建Inserted & Deleted过程的,我们通过简单的例子去测试下

5.  触发器and事务

看出,Update Contact触发tr_Contact触发器操作,触发器里面的Rollback Tran 动作导致了触发器外面的Update语句执行回滚,而Rollback Tran 语句后面的Begin Tran语句,主要是应用于保持整个事务的完整性。为了更能理解这一过程,我模拟了一个触发器中的事务开始结束过程。

图4.

在SQL Server 2005 和 SQL Server 2008上面,可以看到如图4.的效果。在低版本的SQL Server上,可能会出现错误提示情况,不管如何,在触发器外面,SQL Server都会Rollback Tran。下面我做个错误提示的例子。

 

不管如何,在触发器外面,SQL Server都会Rollback Tran。下面我做个错误提示的例子。

在触发器里面没有Begin Tran语句动作,触发器外面也能回滚操作。这里我们可以通过查询表数据和@@Trancount来判断。

         其实,上面的例子,Update语句,是以自动提交事务(Autocommit Transactions)模式 开始执行的,触发器里Rollback Tran后面,不管有没有Begin Tran ,最后都会事务都会交回给SQL Server自动提交事务管理。当然,在DML触发器中,你可以使用显式事务(Explicit Transactions),或开启隐式事务(Implicit Transactions) 来控制,当然你也可以应用于批范围的事务(Batch-scoped Transactions) 中。这里,我通过开启隐式事务(Implicit Transactions) 的例子来说,触发器与事务的关系。

这里,你是否发现一个很有意思的问题,在触发器理,执行Insert ContactHIST之前,@@Trancount=1,执行Insert后,@@Trancount还是为1,触发器外面Update Contact后,@@Trancount就变成了2,。这里可以理解成,你在触发器里面,发出一个Begin Tran,那么SQL Server 就会创建一个嵌套事务。当你在触发器里面,在Rollback Tran后面屏蔽掉Begin Tran,就会出现错误3609,如,

 

 

6. 下面描述三种常见触发器中事务的情况:

图5.                                                                             图6.                                                                           图7.

图5.描述在触发器中含有Begin Tran …… Commit Tran的情况,

图6.描述在触发器中含有Save Tran savepoint_name …… Rollback Tran savepoint_name 的情况,触发器中的Rollback Tran 只会回滚指定的保存点,不会影响到触发器外面的Commit Tran Or Rollback Tran操作。

图7.描述在触发器中含有Rollback Tran的情况,不管触发器里面有没有Begin Tran,都会出现错误3609,中止批处理。

    注:DDL触发器操作可 以触发器中回滚操作,可以使用命令如Rollback,但严重错误可能会导致整个事务自动回滚。不能回滚发生在 DDL 触发器正文内的 Alter Database事件。在触发器中使用Rollback … Begin Tran 可能会导致意想不到的结果,在没有确认和测试情况下,请不要随便在触发器中直接使用Rollback …Begin Tran处理方式.特别是Create Database事件,在SQL Server 2008和SQL Server 2005环境下,产生的结果不同。

 

7.     2、 instead of 触发器 (之前触发)

 

其中after触发器要求只有执行某一操作insert、update、delete之后触发器才被触发,且只能定义在表上。而instead of触发器表示并不执行其定义的操作(insert、update、delete)而仅是执行触发器本身。既可以在表上定义instead of触发器,也可以在视图上定义。

 

 

8. 触发器有两个特殊的表:插入表(instered表)和删除表(deleted表)。

这两张是逻辑表也是虚表。有系统在内存中创建者两张表,不会存储在数 据库中。而且两张表的都是只读的,只能读取数据而不能修改数据。这两张表的结果总是与被改触发器应用的表的结构相同。当触发器完成工作后,这两张表就会被 删除。Inserted表的数据是插入或是修改后的数据,而deleted表的数据是更新前的或是删除的数据。

 

对表的操作

Inserted逻辑表

Deleted逻辑表

增加记录(insert)

存放增加的记录

删除记录(delete)

存放被删除的记录

修改记录(update)

存放更新后的记录

存放更新前的记录

    Update数据的时候就是先删除表记录,然后增加一条记录。这样在inserted和deleted表就都有update后的数据记录了。注意的是:触 发器本身就是一个事务,所以在触发器里面可以对修改数据进行一些特殊的检查。如果不满足可以利用事务回滚,撤销操作。

9. 表格记录复制and迁移SELECT INTO 和 INSERT INTO SELECT

Insert是T-sql中常用语句,Insert INTO table(field1,field2,...) values(value1,value2,...)这种形式的在应用程序开发中必不可少。但我们在开发、测试过程中,经常会遇到需要表复制的情况,如将 一个table1的数据的部分字段复制到table2中,或者将整个table1复制到table2中,这时候我们就要使用SELECT INTO 和 INSERT INTO SELECT 表复制语句了。

 

SELECT INTO  要新的建立表格...INSERT INTO SELECT 可以存在的表格insert 数据..所以,还是.INSERT INTO SELECT  使用的常用...

 

 

ALTER TRIGGER [dbo].[trg_inst]

   ON   [dbo].[t_mb_weixinuser]

   AFTER  INSERT  

AS 

BEGIN

-- SET NOCOUNT ON added to prevent extra result sets from

-- interfering with SELECT statements.

SET NOCOUNT ON;

 Insert into wechatuhstry(userid, [subscribe] ,[openid] ,[subscribe_time],[groupid] ,[createTime] ,[updateTime] ,nickname)   select  userid,[subscribe] ,[openid] ,[subscribe_time],[groupid] ,[createTime] ,[updateTime] ,nickname from inserted;

    -- Insert statements for trigger here

 

END

 

#----最佳实践

copy2表格的id自动incream最好关闭..中间id一样..分享一样的主键.

text类型的不能copy,只好指定字段了...

 

 

#---rest风格安全可以多次复制

 Insert into wechatuhstry 

 select top 100000 * from t_mb_weixinuser  where UserID not in

  (select UserID from wechatuhstry)

 

10. 参考

SQL Server 触发器 - hoojo - 博客园.htm

了解SQL Server触发器及触发器中的事务 - OK_008 - 博客园.htm

 

 

我要啦免费统计
posted @ 2014-08-20 22:36  attilaxAti  阅读(229)  评论(0编辑  收藏  举报