Sql After触发器总结

     SQL解发器,虽然对它有一定认识,但自从我工作这近四年来,还没有写过解发器,我想也有很多朋友像我一样,虽然经常使用ado.net,但无非都是些增删改查的操作。解发器的应用比起存储过程可谓要少的多,至到时最近的一个项目需求,让我想到了解发器的应用场景。

     往往一个公司的IT部门会根据职能或者是业务划分,每个部门负责一部分功能模块,部门之间即独立也有联系,当其它部门所做的功能不能完全满足你的需求时,你有可能需要自己动手来协助完善其功能。

     具体例子:部门A负责酒店的业务,所有酒店查询,订单处理都由他们完成,酒店都有统一的库存管理,但有的酒店比较特殊,可以用积分来换,但这种酒店的库存和正常的酒店库存并不统一,唯一的共同点就是积分兑换的酒店价格与正常酒店价格存在一个比例,例如正常酒店(北京饭店)一晚100元,那么积分酒店(北京饭店)就需要100*100积分。原来积分兑换的酒店价格都由系统录入时手工指定价格,但现在业务变更,需要在录入积分酒店时,自动初始化价格,这个价格就要以对应的正常酒店价格为准。

            问题:初始化价格如何取?
            方法一:修改录入积分酒店的程序。
            优点:处理方便,在录入数据时,先查询到对应正常酒店的价格,然后一并写入数据库。
            缺点:需要其它人支持,如果此段程序无人维护,处理难度会非常大。
            方法二:给原来程序额外打一个补丁。在数据录入数据库后,利用触发器自动初始化价格。
            优点:只需要额外增加一个触发器,改动量相对小。
            缺点:相对方法一的缺点就不值得一说了。


      触发器定义:它是一种类型独特的过程,非常类似C#中的事件。asp.net中,当点击一个按钮,就会触发相应事件。触发器与数据库表相关联,当表中内容发生如下特殊变化时,触发器就会被触发。1:insert;2:update;3:delete。


      说明:本文只探讨after触发器,至于instead-of触发器不在本文讨论范围之内。after触发器的语法我也略过,重点分享下在应用触发器时应该注意的地方。

 

      第一:触发器不会对每条记录都触发一次。例如我们在一次事务中更新或者删除了一条以上的记录,触发器只会触发一次,但能正常反映所有受影响的行。

      第二:使用触发器一定要清楚两个虚似表:
    
          1:inserted,事务中被插入的所有记录。
          2:deleted,事务中被删除的所有记录。
          说明:数据库中不存在updated表,因为数据的更新是先删除然后插入的过程。有了上面两个虚似表,我们就可以在受影响的行上做其它操作,例如在录入积分酒店数据后,利用inserted中的数据信息来更新本记录的某些字段值。

 

      第三:after,从字面意义来看应该是某个操作之后的意思,after触发器就是数据成功插入数据表后执行的操作,如果插入数据失败,对应的触发器是不会引发的。

 

      第四:触发器与开发人员在对于什么样才是对表的成功操作概念上有不同的定义,当更新或者是删除0条记录时,触发器也会被触发,但对于开发人员来说,显然这种触发是没有意义的。此种触发第一是没有意义,第二是占用系统资源,如果你的数据服务器非常繁忙,而且有用户正在锁定数据库表,执行触发器的时间往往比你想象的要多。所以我们希望遇到这种情况应该尽快退出触发器。我们可以用如下代码来完成,此代码一定要在解发器语句的开头部分体现,否则@@rowcount会受到前面代码的影响。
 

IF @@rowcount = 0 
            BEGIN
                PRINT 
'触发器退出'
                RETURN
            END 

   

      第四:不要在存储过程中使用select以及print语句,虽然这两个语句在调试过程中非常好用,但最好不要体现在正式上线环境中,这些语句会产生另外的结果集,如果没有正常处理它们,或者是没有预料到它们的出现,那么这种结果集有可以影响到客户端应用程序的失败。

      第五:触发器管理。

          1:利用sp_helptrigger命令来查看一个表关联的触发器。sp_helptrigger 表名
          2:利用sp_helptext命令来查询某一个触发器的代码。sp_helptest 触发器名。
          3:删除触发器,和删除数据库其它对象类似,drop trigger 触发器名。
          4:修改触发器和生成触发器内容差不多,只不过修改的语句为alter trigger。
          5:利用exec sp_rename命令来完成触发器的重命名。

      第六:触发器中的事务管理。触发器始终是对它进行初始化事务的一部分,这个事务可以是显式的也可以是隐式的。可以在触发器中使用如下脚本来回滚之前的数据操作。在这之前的代码中并不一定要显示的写begin transaction之类的代码。
        

IF @@ERROR <> 0 
            BEGIN
                ROLLBACK TRANSACTION
            END

  

      第七:触发器的执行顺序,对于after触发器来说,一个表可以对应多个after触发器,众多触发器如何来控制它们的执行顺序呢?我们可以利用exec sp_settrggerorder命令来完成,示命如下:

          

代码
          exec sp_settriggerorder @triggername=触发器名称,
                                  @order
='first,或者是last或者是none',
                                  @stmttype
='数据操作类型,例如insert,update或者是delete'

  

     第八:哪些情况下根本不需要使用触发器:
 
          1:如果能够使用约束实现的功能,就不要使用触发器。
          2:如果可以使用存储过程来完成,那么也不分使用触发器。
          说明:触发器的实现,调试,管理比起存储过程都更加困难,如果有更好的方式实现你的需求最好不要使用触发器,除非没有比触发器更简单的方法。
  

     总结:

          选择好适当的场景,触发器往往会有意想不到的效果。本篇文章只提到了after触发器一些比较实用的知识,至于具体应用大家仁者见仁,智者见智。

 


作者:姜敏
出处:http://www.cnblogs.com/aspnet2008/ 

           
posted on 2010-03-26 23:08  min.jiang  阅读(8025)  评论(2编辑  收藏  举报