一、什么是存储过程

   存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。这是百度百科上的解释,可能看这句话觉得有些复杂,但是如果实践一下理解起来就会容易很多。

   我的理解存储过程其实就是编译在数据库中的一组SQL语句,当我们需要执行这些SQL语句时只需要调用这个存储过程就可以了,当然如果存储过程需要参数的话,我们需要给出参数,具体的用法详见下面的实例。

二、我们为什么要用存储过程

1、存储过程可以重复使用,如果多次需要实现这些SQL语句,就可以重复调用这些存储过程,可以减少数据库开发人员的工作量。

2、减少网络流量,存储过程位于数据库上,我们调用的时候只需要传递存储过程的名称和参数就可以了,降低了网络传输的数据量。

3、安全性,参数化的存储过程可以防止SQL注入式攻击,可设定只有某些用户才具有对指定存储过程的使用权

4、我现在体会最深的就是这一条:当对数据库进行复杂操作时(如对多个表进行Update,Insert,Query,Delete时),可将此复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使用。

  有时候我们需要对多个表进行增删改查的时候,我们就可以用到存储过程再结合上我们之前学过的事务就完美了,这些代码都封装到存储过程中,我们在D层直接调用存储过程就好啦。详细问题,下面实例中介绍。 

三、存储过程是在哪都可以用的灵丹妙药吗

  存储过程虽然有诸多好处,但它可不是灵丹妙药什么病都能治。所以我们使用存储过程是有条件的,而且存储过程也是存在缺点的。

1、调试麻烦

2、移植问题,因为存储过程是写在数据库中的,所以如果更换数据库那么维护起来就会很难。

3、重新编译问题,因为后端代码是运行前编译的,如果带有引用关系的对象发生改变时,受影响的存储过程、包将需要重新编译(不过也可以设置成运行时刻自动编译)。

4、如果在一个程序系统中大量的使用存储过程,到程序交付使用的时候随着用户需求的增加会导致数据结构的变化,接着就是系统的相关问题了,最后如果用户想维护该系统可以说是很难很难、而且代价是空前的,维护起来更麻烦。

  综上所述,我们在使用存储过程的时候应该结合实际情况分析我们是否应该使用存储过程,否则就会适得其反。

四、运用存储过程的实例

   因为这次设计数据库的时候尽量减少冗余,而且我的学生上机是学生登录该系统就会上机,所以注册的时候需要同时向卡表、用户表、学生表、充值记录表四张表同时插入数据,这时候就用到了存储过程。将这些SQL语句封装起来返回一个结果,如果其中有一条没有执行成功就会回滚事务,直到完全执行成功,这样D层的代码就会很简单了。

 

-- =============================================
-- Author:		<王雅静>
-- Create date: <2017.5.29>
-- Description:	<注册>
-- =============================================
ALTER PROCEDURE [dbo].[PROC_Register] 
	-- Add the parameters for the stored procedure here
	@CardNo char(15),
	@Cash numeric(5,2),
	@RegisterDate datetime,
	@CardState bit,
	@StudentNo char(15),
	@RechargeCash char(15),
	@RechargeDate datetime,
	@Head char(15),
	@CheckState bit,
	@studentName nchar(10),
	@Sex char(4),
	@Major nvarchar(20),
	@Department nvarchar(20),
	@Grade char(4),
	@Class char(4),
	@UserID char(15),
	@Password char(8),
	@UserName char(10),
	@Level char(8),
	@ReDate datetime

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,Cash,RegisterDate,CardState,StudentNo)values(@CardNo,@Cash,@RegisterDate,@CardState,@StudentNo)
	set @error=@error+@@error
	insert into User_Info(UserID,Password,UserName,Level,ReDate,Head)values(@UserID,@Password,@UserName,@Level,@Redate,@Head) 
	set @error=@error+@@error
	insert into Student_Info(studentNo,studentName,Sex,Major,Department,Grade,Class,Head)values(@studentNo,@studentName,@Sex,@Major,@Department,@Grade,@Class,@Head)
	set @error=@error+@@error
	insert into RechargeCash_Info(CardNo,RechargeCash,RechargeDate,Head,CheckState)values(@CardNo,@RechargeCash,@RechargeDate,@Head,@CheckState)
	set @error=@error+@@error
	if @error <>0
		rollback transaction --如果不等于0,则回滚事务,不能执行
	else
		commit transaction --等于0,则执行该事物
	end

  D层调用存储过程的代码:

 

 

Dim sqlhelper As New SQLHelper.sqlhelper
        Dim cmdType As CommandType = New CommandType()
        Dim sqlparams As SqlParameter() = {New SqlParameter("@CardNo", CardInfo.CardNo),
                                           New SqlParameter("@Cash", CardInfo.Cash),
                                           New SqlParameter("@RegisterDate", DateTime.Now),
                                           New SqlParameter("@CardState", True),
                                           New SqlParameter("@StudentNo", StudentInfo.StudentNo),
                                           New SqlParameter("@studentName", StudentInfo.StudentName),
                                           New SqlParameter("@Sex", StudentInfo.Sex),
                                           New SqlParameter("@Major", StudentInfo.Major),
                                           New SqlParameter("@Department", StudentInfo.Department),
                                           New SqlParameter("@Grade", StudentInfo.Grade),
                                           New SqlParameter("@Class", StudentInfo.stuClass),
                                           New SqlParameter("@Head", UserInfo.UserID),
                                           New SqlParameter("@RechargeCash", CardInfo.Cash),
                                           New SqlParameter("@RechargeDate", DateTime.Now),
                                           New SqlParameter("@CheckState", False),
                                           New SqlParameter("@UserID", CardInfo.CardNo),
                                           New SqlParameter("@Password", CardInfo.CardNo),
                                           New SqlParameter("@UserName", StudentInfo.StudentName),
                                           New SqlParameter("@Level", "学生"),
                                           New SqlParameter("@ReDate", DateTime.Now)
                                          }
        Dim cmdText As String
        cmdText = "PROC_Register"
        Dim result As Boolean
        result = sqlhelper.ExecuteNoQuery(cmdText, CommandType.StoredProcedure, sqlparams)
        Return result

   【总结】我们之前在数据库中学过理论知识,可能当时比较懵懂。在这里实践一下我们学过的理论知识,相信一定会有不一样的体会。