关于触发器要弄清楚的问题(着重后触发器)。

前段时间,论坛中的一个朋友托我帮他写一个触发器。也许是个人对触发器存在一定的偏见,总觉得触发器不是个好东西。做项目一年多来,只要稍微有一点逻辑,我就不用触发器。数据方面难于维护先不说;调试起程序起来,排错也是个问题。如果你不幸还级联了触发器,排错更是困难。以至于长时间不用,触发器的有些特性也渐渐淡了...
     1.触发器的分类。
       根据数据操作语言来分,触发器分为DML触发器和DDL触发器,其中,DDL触发器是子SQL 2005以来新引入的。两者的具体区别在于:DML触发器是为了响应DELETE,UPDATE,INSERT语句;DDL触发器是为了响应CREATE、ALTER、DROP等任何一条修改数据库结构的语句。今天我们只讨论DML触发器。
       根据触发器的处罚时间点来分,触发器分为“后触发器”、“替代型触发器”。后触发器是DELETE、UPDATE、INSERT语句运行后触发的SQL语句;替代性触发器是一发出DELETE、UPDATE或者INSERT语句时,数据库不执行DELETE、UPDATE或者INSERT语句,而直接执行触发器中的SQL语句;从性能上来分析,应该是替代型触发器比较优秀。(因为无论如何,后触发型触发器都必须执行DELETE、UPDATE或者INSERT动作,转而执行触发器中的SQL,而替代型触发器直接执行SQL语句)。
       根据触发器的处罚动作来分,触发器可分为INSERT触发器、DELETE触发器。UPDATE触发器可以看作是INSERT触发器和DELETE触发器的综合。
   2.触发器与事务的关系。在SQL中,你可通过BEGIN TRAN...COMMIT TRAN 来显示地规定一个事务。但实际上,SQL在处理UPDATET、DELETE或者INSERT语句时,都把这些语句当作“隐性事务”来对待。而触发器的语句是被封装在隐性事务里的。所以,你可以在触发器中使用ROLLBACK回滚事务,而不必担心没有BEGIN TRAN来与之对应;当触发器执行失败时,相应的UPDATE、DELETE、INSERT也会失败。
   3.触发器究竟触发多少次?当一条SQL语句只影响一条数据时,很明显,触发器会被触发一次。但是要记住:当一条SQL语句一行数据也影响不了时,触发器也会被触发一次;当一条SQL语句同时影响多行时,触发器还是只能被触发一次(比如UPDATE语句一下更新多行的情况)!当然,你可以通过循环来一条一条INSERT或者UPDATE或DELETE,以保证每影响一条数据后,相应的触发器一定会触发一次。
   4.你可以在触发器的最初通过读取@@ROWCOUNT这个全局变量来判断触发器后面的语句是否要继续执行;而当@@ROWCOUNT的值大于1时,你可以在触发器中写游标以便触发器能正确地处理您的数据。
   5.当后触发器触发后,未执行完触发器中的所有语句时,读触发器所在表的数据时是“脏读”。
   6.当通过触发器来向触发器所来表插入、修改或者删除数据时,不用担心触发器会被递归触发。比如,有一表A上有一INSERT触发器,在触发器中有一INSERT INTO A(...) values (...)语句,当执行触发器中的INSERT语句时,触发器不会再被触发。当然,你可以更改数据库选项recursive triggers 为TRUE来启用触发器的递归,并且也永远不会造成死循环,因为触发器最多只能被递归32次,超过这个次数,当最后一次触发器执行失败时,会回滚到最初导致触发器被触发起的所有修改数据。
   7.当你确实需要触发器级联或者递归时,请精心构造你的触发器,以保证触发器能正确的终止。
   8.当一个表中有多个后触发器时,并且如果你对后触发器的触发顺序有要求,你可以通过系统自带的过程“sp_settriggerorder”来指定“第一个删除触发器”“最后一个删除触发器”“第一个更新触发器”“最后一个更新触发器”“第一个插入触发器”“最后一个插入触发器”。比如说,一个表中有4个INSERT触发器,你可以指定哪个INSERT触发器最先触发和哪个INSERT触发器最后触发,而剩下的两个INSERT触发器的处罚顺序就只能随机了。(注意:替代型触发器是不能指定触发顺序的)
   9.你可以通过ALTER TABLE 语句的DISABLE TRIGGER子句来禁用触发器,从而使触发器暂时失效,直到您重新启用触发器。
   10.有两个特殊的表:Inserted和Deleted。这个两个表分别存储数据的前映像和后映像。你可以通过读取Inserted表中的数据来知道即将向表中插入什么数据;通过读取Deleted表中的数据来知道即将可能要删除什么数据。
   触发器,要注意的问题就这么多了...

posted @ 2008-04-16 18:27  周强  阅读(1888)  评论(5编辑  收藏  举报