前言:
在敲系统的时候,遇到了一个业务功能的执行,需要涉及到多张表的数据的时候。这样就需要在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的结构。
经过上面的探索我得出了一下结论:如果一定要使用,优先选择存储过程。当然视情况而定,没有什么最好的,只有更合适的。