在机房重构还没开始的时候总是听说存储过程如何如何好用,学习《数据库基本原理》这本书时也有提到过存储过程,但一直处于二丈和尚摸不着头脑的状态。没有实战就没有发言权,终于在重构机房的时候有了练手的机会。那么什么情况下会用到存储过程呢?存储过程到底是个什么"高深"的东西呢?存储过程又是如何使用的呢? 听我一一道来。
我是为什么想用存储过程的呢?在重构机房的过程中实现充值这个功能时,每次充值都需要保存到ReCharge这个表中,而ReCharge这个表中有两个关于金额的字段,一个是本次充值金额,另一个是充值后的剩余金额。而这个充值前的剩余金额需要从卡表中获取,在使用七层架构的情况下,则需要两条线才可以完成这个功能,先走一条线返回Card表的该卡号剩余金额,然后 在来一条线保存充值记录。这样可以实现,但代码写起来有些繁琐,对于我这种代码量能少就少的人来说当然是很不乐意这样做喽。正一头莫展的时候,阿丽告诉我说:用存储过程啊!它能一下帮你解决这个问题。就这样,开始尝试深入了解存储过程来了。
那么说了这么多,存储过程到底是什么呢?百度百科给出了这样的解释:存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。华伟哥说简单粗暴的解释存储过程就是一堆SQL语句的合并,中间在加一些逻辑控制。
下面这段代码是我实现注册时的一个存储过程。
-- =============================================
-- Author: <杜雨>
-- Create date: <2017/07/7 11:54>
-- Description:
-- =============================================
ALTER PROCEDURE [dbo].[proc_Register]
-- Add the parameters for the stored procedure here
--定义变量
@cardNo varchar(20),
@studentNo varchar(20),
@Balance numeric(10,2),
@state bit,
@regdate smalldatetime,
@Ischeck bit,
@UserID varchar(20),
@studentName varchar(20),
@sex bit,
@department varchar(50),
@grade char(6),
@specialty varchar(20),
@RechCash numeric(10,2),
@RechDate smalldatetime,
@computer varchar(20)
AS
BEGIN
declare @error int --声明变量(用于事务)
set @error=0 --赋值
BEGIN TRANSACTION --事务开始语句
--添加学生表
insert into Student (studentNo,cardNo,studentName,sex,department,grade,specialty)
values (@studentNo,@cardNo,@studentName,@sex,@department,@grade,@specialty)
set @error=@error+@@ERROR --事务
--添加卡表
insert into Card (cardNo,studentNo,Balance,[state],regdate,Ischeck,UserID)
values (@cardNo,@studentNo,@Balance,@state,@regdate,1,@UserID)
set @error =@error + @@ERROR --事务
--添加充值表
insert into ReCharge (cardNo,RechCash,Balance,RechDate,UserID,computer)
values(@cardNo,@RechCash,@Balance,@RechDate,@UserID,@computer)
set @error =@error + @@ERROR --事务
if @error <> 0
ROLLBACK --发生错误回滚
else
COMMIT --不发生错误插入
END
(1)减少网络通信量。调用一个行数不多的存储过程与直接调用SQL语句的网络通信量可能不会有很大的差别,可是如果存储过程包含上百行SQL语句,那么其性能绝对比一条一条的调用SQL语句要高得多。 、
(2)执行速度更快。有两个原因:首先,在存储过程创建的时候,数据库已经对其进行了一次解析和优化。其次,存储过程一旦执行,在内存中就会保留一份这个存储过程,这样下次再执行同样的存储过程时,可以从内存中直接调用。
(3)更强的适应性:由于存储过程对数据库的访问是通过存储过程来进行的,因此数据库开发人员可以在不改动存储过程接口的情况下对数据库进行任何改动,而这些改动不会对应用程序造成影响。
(4) 布式工作:应用程序和数据库的编码工作可以分别独立进行,而不会相互压制。
(1).如果更改范围大到需要对输入存储过程的参数进行更改,或者要更改由其返回的数据,则您仍需要更新程序集中的代码以添加参数、更新 GetValue() 调用,等等,这时候估计比较繁琐了。
(2).可移植性差
由于存储过程将应用程序绑定到 SQL Server,因此使用存储过程封装业务逻辑将限制应用程序的可移植性。如果应用程序的可移植性在您的环境中非常重要,则将业务逻辑封装在不特定于 RDBMS 的中间层中可能是一个更佳的选择。
(3)大量采用存储过程进行业务逻辑的开发致命的缺点是很多存储过程不支持面向对象的设计,无法采用面向对象的方式将业务逻辑进行封装,从而无法形成通用的可支持复用的业务逻辑框架。
(4).代码可读性差,相当难维护.
区别一,存储过程保存在数据库里面,存储过程可以被连接此数据库的所有程序设计语言和程序使用,自定义函数不能。
区别二,存储过程可以有数据库管理软件修改,使得多层结构程序调整系统逻辑时,并不需要编译和分发程序。
区别三,存储过程执行中,不会引起网络流量,不占用程序服务器的内存和CPU资源。