将AFTER触发器的一些特性和注意事项整理一下,注意以下内容仅适用于MSSQL系列。
1、什么时机触发
在语句执行后触发,注意不论此语句影响了多少行数据(包括0行),都只触发一次。如果原语句因为违反约束等原因未生效,触发器不被触发。
2、触发器SQL与原SQL是一个事务吗
是的,也就是说,如果触发器SQL执行失败了,原SQL也会不成功。
3、同类型的多个触发器冲突吗
如果定义了多个同类型的触发器比如INSERT,除了能定义哪个最先执行和哪个最后执行外,其它的无法控制,是无序串行执行的。
4、inserted表和deleted表的作用
这是两个特殊的表,inserted表包含了受影响行数据的新镜像,deleted表包含了旧镜像。简单点说,你把一行数据从AAA改成BBB,那么在inserted表中此记录是BBB,deleted表中是AAA。
这两个表都与触发器所在表保持同构,但没有索引。
对INSERT操作,只有inserted表有数据,对DELETE操作,只有deleted表有数据,对UPDATE操作,两张表都有数据。
5、如何识别触发器类型
如果一个触发器同时处理INSERT/UDPATE/DELETE操作,又想识别出具体操作,一般的做法是通过inserted表和deleted表来判断,如下:
- IF(EXISTS(SELECT * FROM inserted))
- BEGIN
- IF(EXISTS(SELECT * FROM deleted))
- --有ins也有del,是UPDATE操作
- ELSE
- --有ins无del,是INSERT操作
- END
- ELSE
- BEGIN
- --无ins有del,是DELETE操作
- END
6、如何处理指定列的更新
通过UPDATE()方法来判断,传入列名。
7、怎样才能逐一处理受影响的数据
除非能构造出合适的SQL语句,否则一般情况都是用游标。随便给个例子:
- CREATE TRIGGER [dbo].[TriggerName]
- ON [dbo].[TableName]
- AFTER UPDATE --定义的是UPDATE的后触发器
- AS
- BEGIN
- --无受影响行,直接返回
- IF(@@rowcount = 0)
- RETURN
- DECLARE @tag INT
- --定义并打开一个游标cur,用于从修改后的数据中查一下Tag字段的值
- DECLARE cur CURSOR FAST_FORWARD FOR
- SELECT Tag FROM inserted
- OPEN cur
- --通过游标取数据,把结果放到@tag中
- FETCH NEXT FROM cur INTO @tag
- WHILE(@@fetch_status = 0)
- BEGIN
- --根据@tag来做一些处理,然后再取一条,直到@@fetch_status不为0
- FETCH NEXT FROM cur INTO @tag
- END
- --关闭游标并释放资源
- CLOSE cur
- DEALLOCATE cur
- END
本文转自 BoyTNT 51CTO博客,原文链接:http://blog.51cto.com/boytnt/787562,如需转载请自行联系原作者