机房收费系统的重构中使用了三层,将对数据库的操作放到了D层中,面向对象的思想对D层进行了进一步的抽象抽象出来SQLHlper,但还是避免不了像机房收费系统中类似“注册”这样的功能要同时向多张数据表中增加记录。在机房收费系统中实现“注册”功能时,要同时向卡表、学生信息表、充值记录表三张表增加记录,就算是通过外观层将B层的这三个增加记录的方法组合调用,我们也不能保证在增加记录的过程中不出错,导致在卡表中增加了新的记录而在其他的表中由于错误没有增加记录,为了解决这个问题在重构中就使用了SQL的存储过程。以下以学生注册功能为例,学习存储过程的使用。
首先要在数据库中写入存储过程
然后开始对存储过程进行编写
-- =============================================
-- Author: <杨晓菲>
-- Create date: <2014-12-28>
-- Description: <注册新卡使用的存储过程,同时像卡表、学生信息表、充值记录表增加新注册的记录>
-- =============================================
ALTER PROCEDURE [dbo].[EnrollNewCard] --存储过程的名字为EnrollNewCard
-- =============================================================
-- 如下的变量是向三张表中增加记录时会用到的
@cardID int,@studentID int,@cardType nchar(10),@cardBanlance decimal(10,3),
@operaterID int,@isCheck nchar(10),@studentName nchar(10),@studentSex nchar(10),
@isCount nchar(10),@studentClass nchar(10),@studentGrade nchar(10),
@studentAbout nchar(10),@studentMajor nchar(10),@stuEnrollDay nchar(10),
@stuEnrollTime nchar(10),@state nchar(10),@cardConsume decimal(10,3)
-- =============================================================
AS
BEGIN
--向学生信息表中增加记录
Insert Into T_StudentInfo(studentID,studentName,studentSex,studentGrade,studentClass,studentMajor,studentAbout,stuEnrollTime,stuEnrollDay,cardID,enrollID,state)values(@studentID,@studentName,@studentSex,@studentGrade,@studentClass,@studentMajor,@studentAbout,@stuEnrollTime,@stuEnrollDay,@cardID,@operaterID ,@state)
--向卡表中增加记录
insert into T_Card (cardID,cardType,cardBanlance,operaterID,state,isCheck,studentID,cardConsume,isCount ) values(@cardID,@cardType,@cardBanlance,@operaterID,@state ,@isCheck,@studentID,@cardConsume,@isCount )
--向充值记录表中增加记录
insert into TR_CardUser_ReCharge (cardID,operaterID,rechargeCash,rechargeDay,rechargeTime,isCheck)values(@cardID,@operaterID,@cardBanlance,@stuEnrollDay,@stuEnrollTime,@isCheck)
END
在SQL中的存储过程写好之后开始在机房重构的程序中进行调用
首先是在SQLHlper中增加了针对存储过程的的方法。
''' <summary>
''' 执行sql中的存储过程,非查询的
''' </summary>
''' <param name="cmdTxt">参数sql语句</param>
''' <param name="paras">对数据表进行操作需要的参数</param>
''' <returns>返回执行的结果</returns>
''' <remarks></remarks>
Public Shared Function ExecuteProcedure(ByVal cmdTxt As String, ByVal paras As SqlParameter()) As Integer
'定义链接的字符串,同时使用配置文件对ConnStr进行配置
Dim strConnStr As String = System.Configuration.ConfigurationManager.AppSettings("ConnStr")
'定义一个链接,他的参数是建立的链接字符串
Dim conn As SqlConnection = New SqlConnection(strConnStr)
'定义一个命令,在实例化时进行初始化
Dim cmd As SqlCommand = New SqlCommand(cmdTxt, conn)
cmd.CommandType = CommandType.StoredProcedure '设置命令的类型为存储类型
cmd.CommandText = cmdTxt '这里写入的是存储过程的名称
cmd.Parameters.AddRange(paras) '添加参数
'定义一个整型变量,返回最后收影响的记录数
Dim res As Integer
Try
If conn.State = ConnectionState.Closed Then
conn.Open()
End If
res = cmd.ExecuteNonQuery()
Catch ex As Exception
MsgBox(ex.Message, , "数据库操作")
Finally
If conn.State = ConnectionState.Open Then
conn.Close()
End If
End Try
Return res
End Function
在D层中的调用如下:
Public Function EnrollNewCard1(entityCard As Entity.Model.CardEntity, entiryStu As Entity.Model.StudentInfoEntity) As Boolean Implements IDAL.IEnrollNewCard.EnrollNewCard
'如下为增加的参数
Dim paras As SqlParameter() = {
New SqlParameter("@cardID", entityCard.cardID), New SqlParameter("@studentName", entiryStu.studentName),
New SqlParameter("@studentSex", entiryStu.studentSex),
New SqlParameter("@studentClass", entiryStu.studentClass),
New SqlParameter("@studentGrade", entiryStu.studentGrade),
New SqlParameter("@studentAbout", entiryStu.studentAbout),
New SqlParameter("@studentMajor", entiryStu.studentMajor),
New SqlParameter("@stuEnrollDay", entiryStu.stuEnrollDay),
New SqlParameter("@stuEnrollTime", entiryStu.stuEnrollTime),
New SqlParameter("@state", entityCard.state)}
Dim strProc As String = "EnrollNewCard" '该字符串为存储过程的名字
Dim result As Integer
result = SQLDBHlper.ExecuteProcedure(strProc, paras) '调用SQLHlper中的执行存储过程的方法
If result = 0 Then '如果返回的结果是“0”说明添加失败
Return False
Else
Return True
End If
End Function
这样在U层的窗体输好要注册的信息时,只需要通过B层调用D层的该方法即可,不用调用多了D层的方法分别向数据库的表中增加记录。
小结
在准备自考的过程中存储过程只是了解到了而且看的云里雾里,现在是真正的用到了,理解就容易多了,编写好的SQL存储过程和程序结合,不仅能够减少程序的代码还能简化代码的逻辑。
现在越来越明白为什么米老师会说学的东西掌握80%就可以了,剩余的不是不要了,而是在以后的学习别的知识或实践的过程中会有进一步的体会。