给D层减负——存储过程与触发器的使用

  前言:

    在敲系统的时候,遇到了一个业务功能的执行,需要涉及到多张表的数据的时候。这样就需要在D层写至少两个以上的函数,增加了D层的代码。为了让D层看起来简单一些,我们可以在数据库上做一些优化,这就需要借助我们只听说,没用过的“存储过程”和“触发器”了。(在第一次敲机房收费系统的时候,以为是什么高大上,难理解的东西,就没敢用。这次终于看到了它们的庐山真面目了)。


    一、认识一下


    (一)存储过程


     1、优点:重复使用。提高性能。减少网络流量。安全防注入。
     2、缺点:调试麻烦。移植问题。重新编译问题。
        总之,存储过程只在扩建时进行有且只有一次的编译,之后就只是调用。不需要重新编译。但后期的维护工作是有挑战性的。


     (二)触发器


      1、优点:级联修改。“隐形”调用。
      2、缺点:不能使用控制语句。不能用long,longraw类型。
         总之,触发器功能虽强大,但其执行是有条件限制的,若过分依赖,势必会影响DB的结构。


  二、不同点

         

   (一)执行条件不同


    触发器主要是通过事件执行触发而被执行的,而存储过程可以通过存储过程名称名字而直接调用。当对某一表进行诸如UPDATE、INSERT、DELETE这些操作时,SQLSERVER就会自动执行触发器所定义的SQL语句,从而确保对数据的处理必须符合这些SQL语句所定义的规则。

   (二)执行的灵活性不同


    触发器是强制实行的,只要满足了触发的条件,用户是不能绕过触发器的。而相比之下,存储过程则相对具有灵活性,在我们的代码中,可以决定什么时候调用存储过程。存储过程就像函数一样,用Execute语句来执行。


   三、相同点


    二者非常相似,本质上都是SQL语句集。可以说,触发器是特殊的储存过程。当用户执行一个动作,而数据库需要做多处更新的时候,我们就可以考虑去使用它们了。使得D层可以轻松可靠的实现许多复杂的功能。


   四、应用举例


    1、存储过程的应用


    注销卡,分两步,先插入一条新纪录到销卡表,再将卡表中的信息删除。当然,为了保证数据库的完整性与安全性,可以在存储过程中加上事务的执行。注意参数类型,如果成功执行,但返回值是0,很可能是参数的数据类型有问题。写好后,在D层中调用SQLHelper类,把命令类型的参数传入CommandType.StoredProcedure,就可以识别命令的属性了。

    存储过程的编写如下:
<span style="font-family:FangSong_GB2312;">CREATE procedure [dbo].[Proc_CancelCard] 
    -- Add the parameters for the stored procedure here
    @cCNO varchar(10),
    @cCancel varchar(10),
    @cDate varchar(10),
    @cTime varchar(10),
    @cUID varchar(10),
    @cIsCheck varchar(10)
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT OFF;
    -- Insert statements for procedure here
    --Delete T_Card where cNo =@cCNO  
    insert into T_Cancel (cCNO,cCancel,cDate,cTime ,cUID ,cIsCheck )values(@cCNO ,@cCancel ,@cDate ,@cTime ,@cUID ,@cIsCheck)
    Delete T_Card where cNo =@cCNO 
END</span>

    2、触发器的应用


    当用户执行充值的动作时,需要在充值表中插入一条记录,同时将card表中的金额加上充值的金额。recharge表中保证提取的是最新一条充值记录,card表中保证更新的记录满足卡号等于充值卡号。触发器不需要在D层中写什么代码调用,它是“隐形”调用的。
    触发器的编写如下:
<span style="font-family:FangSong_GB2312;">CREATE TRIGGER [dbo].[CardCash]
  on [dbo].[T_Recharge]
  for Insert
 AS
  BEGIN
  UPDATE T_Card set sCash  =sCash  +(select top 1 rAdd  from T_Recharge order by rNo desc) Where T_Card .cNo in (select top 1 cNo  from T_Recharge order by rNo desc )  
  END</span>


  五、总结


    以这种SQL语句集形式存在的触发器和存储过程,让我们可以只写一个函数就能操作多个表记录。在我们认识了它们强大的一面之后,不要忘了过度的使用也会带来副作用。若一个DB过分依赖于二者,势必会破坏DB的结构。
    经过上面的探索我得出了一下结论:如果一定要使用,优先选择存储过程。当然视情况而定,没有什么最好的,只有更合适的。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 119
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 119
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值