最初接触存储过程是在耿建玲老师的视频里,当初仅仅是草草过了一遍。仅仅是有了个印象。知道了这个名词;大二时也有SqlServer数据库这门课,只是老师没讲,自己也没看;真正对存储过程的了解来自于自学考试中的《数据库系统原理》,在考试中,知道存储过程是干嘛的。在纸上怎么写,但从来没有在DBMS中亲手敲过。于是机房收费系统给了我这个机会。

在这里不再过多叙述关于存储过程德基本知识,仅仅写一下在机房收费系统这个小项目中是怎样用到存储过程的。

背景:

机房收费系统中有一个注冊的功能,原型图例如以下:



        

        注冊时。须要对数据库中的三个表进行更新(向卡表T_Card、学生表T_Student、充值表T_Register中分别新增一条记录),所以,运行时,假设用运行SQL语句的方式,那就须要运行三次SQL语句:

1:向卡表T_Card加入记录

 insert into T_Card(cardNumber ,balance ,type ,stuNumber ,status ,isChecked ) values(@cardNumber ,@balance, @type ,@stuNumber ,@status ,@isChecked )

2:向学生表T_Student加入记录

 insert into T_Student (stuNumber,stuName,stuSex,stuMajor,stuGrade,stuClass  ,comment ) values (@stuNumber ,@stuName ,@stuSex ,@stuMajor ,@stuGrade ,@stuClass,@comment )

3:向充值表T_Register加入记录

insert into chargesystem.dbo.T_Recharge (userID,cardNumber,rechargeCash ,rechargeDate ,rechargeTime ,isChecked )values(@userID,@cardNumber ,@balance, CONVERT(varchar,getdate(),120),CONVERT(varchar,GETDATE(),108),'未结账')

存储过程的使用

对于上面的需求,假设用存储过程,在数据库里建立存储过程之后,在代码里仅仅需负责直接运行这个存储过程就可以,而不用连续多次连接、操作数据库。

一、建立存储过程

建立存储过程有两种方法(由于系统用的数据库为SqlServer2008,所以这里以此为例):

(1)、手动建立存储过程:

对象资源管理器中:数据库→ChargeSystem(数据库名称)→可编程性→右键“存储过程”→新建存储过程



        新建的存储过程能够说是一个已经成型的存储过程德模板。我们仅仅需在上面改动一下存储过程名称、參数、运行语句等代码就OK了。

(2)、SQL语句加入存储过程

直接新建查询。在代码编辑窗体编写存储过程SQL代码,基本的语法为:

         CREATE  PROCEDURE  PROC_NAME

               @[參数名] [类型],@[參数名] [类型]……

         AS

         BEGIN

               [过程体].........

         END

用第一种方法建立的存储过程基本上也是这个结构。增加对应的參数和过程体之后,完整的存储过程为:

CREATE PROCEDURE PROC_Register
-- 定义參数
@cardNumber varchar(6),@balance decimal(5,1),@type nvarchar(20),@status nvarchar(50),@isChecked nvarchar(10),
@stuNumber varchar(18),@stuName nvarchar(10),@stuSex varchar(6),@stuMajor nvarchar(30),@stuGrade nvarchar(20),@stuClass nvarchar(20),@comment nvarchar(100),
@userID varchar(18)
AS
BEGIN --向表中插入数据
insert into ChargeSystem .dbo.T_Card(cardNumber ,balance ,type ,stuNumber ,status ,isChecked ) values(@cardNumber ,@balance, @type ,@stuNumber ,@status ,@isChecked )
insert into ChargeSystem .dbo.T_Student (stuNumber,stuName,stuSex,stuMajor,stuGrade,stuClass ,comment ) values (@stuNumber ,@stuName ,@stuSex ,@stuMajor ,@stuGrade ,@stuClass,@comment )
insert into chargesystem.dbo.T_Recharge (userID,cardNumber,rechargeCash ,rechargeDate ,rechargeTime ,isChecked )values(@userID,@cardNumber ,@balance, CONVERT(char(10),getdate(),120),CONVERT(varchar,GETDATE(),108),'未结账')
END

注意:不管是用哪种方式建立的存储过程。都须要点击运行来存到server里。才干够通过以后的调用来运行,单纯地保存(ctrl+C)仅仅是把这个存储过程文件保存在本地,而不会存入数据库server中。

当建立好存储过程时,能够新建查询运行“exec 存储过程名 @參数1=值1,@參数2=值2……”来验证存储过程是否正确。

二、代码中调用存储过程

调用存储过程跟运行SQL语句的方式大同小异,须要注意的是,运行SQL语句时。命令对象Command的CommandType的值为CommandType.Text,而运行存储过程时。CommandType的值为CommandType.StoredProcedure。

        在本例中详细代码为:

D层代码:

Public Class SqlServerRegisterDAL : Implements IDAL.IRegister
Public Function Insert(ByVal enCard As Entity.CardEntity, ByVal enStudent As Entity.StudentEntity, ByVal userID As String) As Boolean Implements IDAL.IRegister.Insert
Dim sqlHelper As New SqlHelper '定义SqlHelper实例
Dim cmdType As CommandType = CommandType.StoredProcedure '定义数据库命令类型
Dim cmdText As String = "PROC_Register" '数据库运行字符串
Dim parameters As SqlParameter() '定义參数数组,负责向存储过程中的变量传值
'为參数数组中的參数一一赋值
parameters = {New SqlParameter("@cardNumber", enCard.CardNumber), New SqlParameter("@balance", enCard.Balance),
New SqlParameter("@type ", enCard.CardType), New SqlParameter("@status", enCard.Status),
New SqlParameter("@isChecked", enCard.IsChecked), New SqlParameter("@stuNumber", enStudent.StuNumber),
New SqlParameter("@stuName", enStudent.StuName), New SqlParameter("@stuSex", enStudent.StuSex),
New SqlParameter("@stuMajor", enStudent.StuMajor), New SqlParameter("@stuGrade", enStudent.StuGrade),
New SqlParameter("@stuClass", enStudent.StuClass), New SqlParameter("@comment", enStudent.StuComment),
New SqlParameter("@userID", userID)}
'推断是否有查询结果
If sqlHelper.ExecuteNonQuery(cmdText, cmdType, parameters) Then
Return True
Else
Return False
End If
End Function
End Class

SqlHelper代码:

Public Class SqlHelper
'从配置文件里获取连接字符串的值
Dim strConnection As String = ConfigurationSettings.AppSettings("strConnection")
'创建数据库连接对象conn
Dim conn As SqlConnection
'创建数据库操作类cmd
Dim cmd As New SqlCommand ''' <summary>
''' 构造函数,实例化类时就初始化数据库连接对象
''' </summary>
''' <remarks></remarks>
Public Sub New()
conn = New SqlConnection(strConnection)
End Sub ''' <summary>
''' 关闭释放SqlCommand对象
''' </summary>
''' <param name="cmd">须要关闭的SqlCommand对象</param>
''' <remarks>cmd.Dispose()直接释放command资源,不知这么做对系统性能怎么样,先这么着,以后再继续优化</remarks>
Public Sub CloseCommand(ByVal cmd As SqlCommand)
If Not IsNothing(cmd) Then
cmd.Dispose()
cmd = Nothing
End If
End Sub ''' <summary>
''' 关闭数据库连接
''' </summary>
''' <param name="conn">须要关闭的SqlConnection对象</param>
''' <remarks>关闭数据库连接。但并没有释放,而是存储在连接池中。须要的时候还能够通过Open()方法打开连接</remarks>
Public Sub CloseConnection(ByVal conn As SqlConnection)
If Not IsNothing(conn) Then
conn.Close()
End If
End Sub ''' <summary>
''' 有參数的 增 删 改 操作
''' </summary>
''' <param name="cmdText">须要运行的SQL命令</param>
''' <param name="cmdType">所运行命令的。通常是sql语句、存储过程或表</param>
''' <param name="sqlParameters">參数数组</param>
''' <returns>返回受影响的行数 类型为整型</returns>
''' <remarks></remarks>
Public Function ExecuteNonQuery(ByVal cmdText As String, ByVal cmdType As String, ByVal sqlParameters As SqlParameter()) As Integer Try
conn.Open() '打开数据库连接
cmd.CommandText = cmdText '设置查询语句
cmd.CommandType = cmdType '设置一个值,解释cmdType(假设值为StoredProcedure时。调用的是存储过程)
cmd.Connection = conn '设置连接
cmd.Parameters.AddRange(sqlParameters) '传入參数 Dim affectedRows As Integer
affectedRows = cmd.ExecuteNonQuery
Return affectedRows '返回运行所受影响行数
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.OkOnly, "温馨提示")
Return 0 '假设出错,则返回0
Finally
cmd.Parameters.Clear() '清楚參数
Call CloseCommand(cmd) '关闭并释放Command
Call CloseConnection(conn) '关闭连接conn
End Try End Function
End Class

为什么要使用存储过程

注冊学生卡号在这个系统中不算个大模块,但这个小小的需求。须要与数据库中三个表的数据打交道。而在以往的操作,居然连了三次数据库。运行了三次SQL语句。

这样频繁地打开与关闭与数据库的连接。须要消耗大量系统资源,减少运行速度。

这时就须要考虑用存储过程来取代运行如此之多的SQL语句。

1、一般SQL语句每运行一次就须要编译一次,而存储过程仅仅是在创造时进行编译,以后每次运行都不须要再进行编译。

2、存储过程就是相当于把多个须要运行的SQL语句集合起来,变成一条SQL语句,当然就仅仅需连接和运行一次就能够得到结果。

3、安全性高。

能够指定存储过程的使用权,防止SQL注入。

4、系统升级、维护比較方便。

总结:

★ 当涉及到多个SQL语句运行,须要多次连接数据库。或者须要对多张表进行处理时,能够将这些操作封装在一起,即创建存储过程。以后每次须要的时候直接调用运行。就可以运行全部的操作,避免了多次打开、关闭数据库连接。

★ 当涉及到比較复杂的需求时(比方机房收费系统中的下机结算消费金额就能够採用存储过程)。比方排序、计算等等。能够把数据直接传到存储过程,一系列操作在数据库server里进行,减小了client与server之间的数据流量,同一时候还保证了系统的安全性。

到了这里大家脑子里可能会有个问题:既然让一个存储过程运行多个任务,那么万一在运行的过程中,这些任务中的一个或者几个任务没有完毕。该怎样是好?这时事务就派上用场了…快去实践吧…

机房收费系统(VB.NET)——存储过程实战的更多相关文章

  1. 机房收费系统vb.net之打包与部署(一)

    从机房重构到如今,我最大的感受就是万事开头难,万事结尾难!开头难是由于那个思路理不清,对三层已经设计模式的应用不够熟悉,结尾难就是打包部署了!这几天非常头疼,以为完毕了代码就大功告成了,但是没想到啊, ...

  2. 机房收费系统vb.net之打包与部署(二)

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/wangdan199112/article/details/28286365             ...

  3. VB.NET版机房收费系统---导出Excel表格

    datagridview,翻译成中文的意思是数据表格显示,使用DataGridView控件,能够显示和编辑来自不同类型的数据源的表格,将数据绑定到DataGridView控件很easy和直观,大多数情 ...

  4. vb.net机房收费系统——存储过程

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/xdd19910505/article/details/35574125 一.使用背景         ...

  5. VB.NET版机房收费系统---七仙女之系统登录

    VB.NET第一版机房收费系统,告一段落,验收的时候.问题也是大大的存在,没实用上设计模式,什么触发器.存储过程,都没实用上.看看其她小伙伴的,七层实现登录?那是什么东东,相比較我的三层而言,多了两倍 ...

  6. VB.NET 机房收费系统项目总结

    VB.NET机房收费系统项目总结 从2013年5月3日——2013年8月20日历时三个多月的.NET机房收费系统终于完成了.项目做完了,真有一种如释重负的感觉. 下面我将从文档.UML图,代码这三个方 ...

  7. 机房收费系统(VB.NET)个人版总结

    重构版个人机房收费系统大概从暑假开学開始进行.花了不到一个半月的时间才完毕.以下对我在重构过程中的一写理解. 1.系统设计一个非常重要的目的就是重用.而要做到重用,低耦合是最有效的手段回想一下我们C/ ...

  8. VB.net版机房收费系统——结账功能实现(调错与优化)

    调错部分 上一篇博客<VB.net版机房收费系统--结账功能实现(代码部分>说的是结账功能的实现,亮出了代码.是在为这篇博客做铺垫.尽管结账功能代码是借鉴的巨人的博客.可是自己比着葫芦画瓢 ...

  9. 机房收费系统——在VB中将MSHFlexGrid控件中的数据导出到Excel

    机房收费系统中,好多查询的窗体都包含同一个功能:将数据库中查询到的数据显示在MSHFlexGrid控件中,然后再把MSHFlexGrid控件中的数据导出到Excel表格中. 虽然之前做过学生信息管理系 ...

随机推荐

  1. StreamCQL

    StreamCQLhttps://github.com/HuaweiBigData/StreamCQL http://blog.csdn.net/viewcode/article/details/90 ...

  2. 怎么查看和修改 MySQL 的最大连接数?

    一. 查看Mysql当前配置 MySQL 默认的最大连接数为 100,可以在 mysql 客户端使用以下命令查看 mysql> show variables like '%connections ...

  3. 学习笔记-[Maven实战]-第三章:Maven使用入门(2)

    使用maven执行编译和测试 1.maven执行编译 (1).在pom.xml上点右键,选择Maven build... (2).在Goals里输入clean complie,执行编译 执行结果: [ ...

  4. 【HDOJ】1263 水果

    hash,使用stl map ac.学了find_if等强大的东西,第一次使用stl模板. #include <iostream> #include <cstdio> #inc ...

  5. JQuery对XML文件的操作

    xml文件如下: <?xml version="1.0" encoding="utf-8" ?> <Root> <Parent&g ...

  6. HDU 1518

    思路:从第一个数开始搜索,将其和与边长比对,相等则计数+1,计数达到3的时候说明可以组成,因为剩下那条必与边长相等,搜索过程注意剪枝,若某个数已被加入边长则不能重复计算,应将其标记,另外应在每一层递归 ...

  7. 基于duilib实现的可滑动tab标签控件

    最近一直在忙棋牌游戏大厅的开发,使用了duilib界面库,在大厅界面游戏菜单的展现上需要用到滑动的效果,类似悠扬棋牌,jj棋牌的菜单左右(上下)滑动的效果.通过自己的设计思路完善了一个可滑动的tab标 ...

  8. Unity 打包后文件系统访问的一个小细节

    Android: 使用 File 类 来访文本文件系统不区分大小写:但是访问 jar 包内的文件是区分大小写的,比如使用 www类,都需要区分大小写. iOS: 使用 File 类 来访文本文件系统严 ...

  9. 引用类型传递 ListView展示数据

    教师评分项目总结 //创建一个SE员工类 1.1       //首先分析项目 * 01.我需要在LIstView控件中显示三个员工的信息 * 那么可以定义一个长度为3的数组来承载要显示的数据 * 0 ...

  10. 输入一个正数 n,输出所有和为 n 连续正数序列。 java实现

    用了半小时才写出来啊, 其实这种思路应用范围很广,利用有序性这个特点,比如本体只要是有序就行,例如两个集合是有序的,求交集,有序数组的查找,有序数组的归并,有序有了优化的可能. 输入一个正数 n,输出 ...