前言
存储过程:它是一组预先编译好的Transact-SQL语句。将其放在服务器上,由用户通过指定存储过程的名字来执行它。存储过程可以作为一个独立的数据库对象,也可以作为一个单元被用户的应用程序调用。存储过程可以接收和输出参数,返回执行存储过程的状态值,还可以嵌套调用。
简单理解存储过程可以说是一个记录集吧,它是由一些T-SQL语句组成的代码块,这些T-SQL语句代码像一个方法一样实现一些功能(对单表或多表的增删改查),然后再给这个代码块取一个名字,在用到这个功能的时候调用他就行了。
示例
先说说如何使用吧
打开数据库-打开“可编程性”-然后右击“存储过程”-新建即可
当选择新建之后,会系统会自动出现生成一些SQL语句。这些生成的语句是建立一个存储过程的模板,遵照这些固定的格式,就可以建立相应的存储过程。
以下是重构注册中的存储过程:基本原理是先将涉及的表中的所有字段写出来(方便D层调用),再将每个表独立出来并将字段也写出来,最后通过判断是否需要同时向三个表中存入信息,要么不存入,要么存入。
-- =============================================
-- Author: <吕德彪>
-- Create date: <2017/6/4>
-- Description: <创建注册过程,向卡表,学生表和充值表中插入数据>
-- =============================================
ALTER PROCEDURE [dbo].[proc_CancelCard]
-- Add the parameters for the stored procedure here '添加必要参数
@cardNo nchar(20),
@UserID nchar(10),
@rechargeMoney char(10),
@date date,
@time time(7),
@sNo char(10),
@age char(10),
@sex char(4),
@department nvarchar(20),
@grade char(4),
@Class char(10),
@status bit,
@registerDate nvarchar(50),
@balance char(10),
@type nvarchar(50),
@IsCheck bit
AS
BEGIN
declare @error int
set @error = 0
begin transaction
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
--SET NOCOUNT ON;
-- Insert statements for procedure here
insert into Card_Info(cardNo,registerDate,balance,type,status,Ischeck,sNo) values(@cardNo,@registerDate,@balance,@type,@status,@Ischeck,@sNo)
set @error=@error+@@error
insert into Student_Info(cardNo,sNo,UserID,age,sex,department,grade,Class,status) values(@cardNo,@sNo,@UserID,@age,@sex,@department,@grade,@Class,@status)
set @error=@error+@@error
insert into Recharge_Info(cardNo,UserID,rechargeMoney,date,time) values(@cardNo,@UserID,@rechargeMoney,@date,@time)
set @error=@error+@@error
if @error<>0
rollback transaction--如果不等于0,则回滚事务,不能执行
else
commit transaction--如果等于0,则执行该事务
END
创建了存储过程,那么如何使用呢?下边是我D层的代码
//注册
public bool Regist(Entity.StuLineBalance regist)
{
List<SqlParameter> reglist = new List<SqlParameter>();
reglist.Add(new SqlParameter("@cardNo", regist.cardNo));
reglist.Add(new SqlParameter("@sNo", regist.sNo));
reglist.Add(new SqlParameter("@UserID", regist.UserID));
reglist.Add(new SqlParameter("@age", regist.age));
reglist.Add(new SqlParameter("@sex", regist.sex));
reglist.Add(new SqlParameter("@department", regist.department));
reglist.Add(new SqlParameter("@grade", regist.grade));
reglist.Add(new SqlParameter("@Class", regist.Class));
reglist.Add(new SqlParameter("@rechargeMoney", regist.rechargeMoney));
reglist.Add(new SqlParameter("@date", regist.date));
reglist.Add(new SqlParameter("@time", regist.time));
reglist.Add(new SqlParameter("@registerDate", regist.registerDate));
reglist.Add(new SqlParameter("@balance", regist.balance));
reglist.Add(new SqlParameter("@status", regist.status));
reglist.Add(new SqlParameter("@type", regist.type));
reglist.Add(new SqlParameter("@IsCheck", false));
SqlParameter[] sqlParams = reglist.ToArray();
string sql = "proc_CancelCard";
bool result = SqlHelper.sqlhelper.ExecuteNonQuery(sql, CommandType.StoredProcedure, sqlParams);
return result;
}
通过此次对存储过程的应用,着实是感到了存储过程的强大之处。如果不用存储过程,在D层需要写三次插入语句。对于这样一些需要处理复杂的数据表之间的逻辑的,存储过程的效率明显高于直接调用。
辩证看待
对于存储过程,一直都存储着争议,有人对他爱不释手,也有人对他不怎么待见。其实事物存在总有他的理由,很多事物我们都应该辩证的看待。是用存储过程好,还是用sql语句好,这个没有绝对的,要看当时具体的情况。
后期难维护?
后期难以维护其实是业务逻辑的归属问题,到底是业务逻辑是由数据层处理(用存储过程),还是放在业务逻辑层,这个要看程序的复杂程度,如果使用的数据表很多,并且业务逻辑复杂,那么用存储过程的话,如果后期需要移植的话,移植成本会相当的高;如果不用存储过程,放在业务逻辑层,移植能力就会提高很多。 存储过程对于处理复杂的数据表之间的逻辑是很有好处的,速度快,尤其是对需要经常调用的地方,比如一项操作,需要从数据里取出多种数据,
另外,如果是多人合作的话,当需要更改存储过程的时候根本不知道这个存储过程具体在什么地方调用,不过这种情况的前提是没有文档,如果有文档的话,什么地方用了,很容易找到,维护还是很方便的。
存储过程也不是维护简单或者难的问题,这要看你对存储过程的调用管理上是否做得好,比如,某个存储过程,需要多输出一个参数,那如果你的数据层的东西做得不好,就得到处去找,哪个地方使用了这个存储过程,然后一个一个去加参数。如果数据层做得好,直接改一个地方,那维护还是很方便的。 存储过程对于处理复杂的数据表之间的逻辑是很有好处的,速度快,尤其是对需要经常调用的地方,比如一项操作,需要从数据里取出多种数据,那如果不使用存储过程的话,通过ado(ado.net)会要经过几次的操作,效率很低。
何时不建议用存储过程
1、如果你的项目要适应不同的数据库,最好不要用存储过程,而且最好用标准的sql语句在,这样便于维护和部署;如果只是一种数据库,那就选存储过程,
2、如果有比较复杂的业务逻辑 不建议放进存储过程。SP虽然能够成功可靠高效完成功能,但是大篇幅的SP很难让后来的维护者阅读和调试,容易在业务变化过程中带来高成本的维护代价,而且极大的增加”越改问题越多”的几率。
3、只有简单的查询语句,不建议使用
4、存储过程是调用以后常驻内存的,对于一些不常用的语句,建议不用。
结语
把业务规则放在中间层做在业务变化的情况下容易维护,而且结构清晰。但是需要在“结构”“维护”和“可靠”性中间做一个权衡,将大部分的业务逻辑放在中间层,少量非常重要的,需要高可靠性的逻辑直接写在过程中。就是“中庸”之道。 4、这个世界实在是太多的不完美了,所以解决方案也总是不完美,但是我们只能选择一个相对较好的,什么好处都占的事情几乎没有。和芝麻的关系。