【机房重构】——存储过程(Stored Procedure)

【前言】

在学习数据库知识时,就曾经接触过存储过程,当时只是如蜻蜓点水一般,短暂的停留,并没有留下什么印象,在进行机房重构学习过程中,又重新认识了存储结构,从开始的抵触,不想用到后来逐渐了解,学着使用,思路越来越清晰,真正去做了才发现了其中的乐趣;常常说学习需要多总结,现在就是在积累,每一次的收获都要整理记录,才能留下深刻的印象,下面就来学习一下存储过程的知识吧。

【存储过程的概念】

在采用客户机/服务器(C/S)计算模式的数据库系统中,很多工作可以在客户端完成,也可以在服务器端完成,数据库除了存放数据,还存放程序,由于这种程序以数据库对象的形式存储在数据库中,因此称为存储过程。

存储过程是使用SQL语句和流程控制语句编写的模块,存储过程经编译和优化后存储在数据库服务器端的数据库中,使用时调用即可。

存储过程中可以包含逻辑控制语句和数据操纵语句,它可以接受参数、输出参数、返回单个或多个结果集以及返回值。

我的理解:存储过程是为了完成某个特定功能的一组SQL语句,将多条相关联的SQL语句集合在一起,存放在数据库中,第一次编译之后再次调用直接调用,不需要再进行第二次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。

【存储过程的使用】

1、预先了解——创建存储过程

① 打开数据库,进行如下操作:

② 参数说明:

<span style="font-family:KaiTi_GB2312;font-size:18px;">CREATE PROCEDURE <Procedure_Name, sysname, ProcedureName>  (名字:指定要创建的存储过程的名称,命名必须符合命名规则,在一个数据库中或对其所有者而言,存储过程的名字必须唯一)
	-- Add the parameters for the stored procedure here (参数:在CREATE PROCEDURE语句中,可以声明一个或多个参数,当调用该存储过程时,用户必须给出所有的参数值,除非定义了参数的默认值)
	<@Param1, sysname, @p1> <Datatype_For_Param1, , int> = <Default_Value_For_Param1, , 0>,
	<@Param2, sysname, @p2> <Datatype_For_Param2, , int> = <Default_Value_For_Param2, , 0>
AS
BEGIN
	-- SET NOCOUNT ON added to prevent extra result sets from
	-- interfering with SELECT statements.
	SET NOCOUNT ON;

    -- Insert statements for procedure here
	SELECT <@Param1, sysname, @p1>, <@Param2, sysname, @p2>(操作语句:存储过程中要包含的任意数目和类型的Transact-SQL语句)
END</span>

2、具体实战——结合机房收费系统

不使用存储过程

机房收费系统的充值功能实现需要执行两条SQL语句,将充值记录插入到充值表中,并且更新卡表中的卡内金额——相关代码(D层):

<span style="font-family:KaiTi_GB2312;font-size:18px;">Public Function InsertRecharge(card As ECard, recharge As Erecharge) As Boolean Implements IRecharge.InsertRecharge
        Dim flag1 As Boolean
        Dim flag2 As Boolean

        Dim SqlParams As SqlParameter() = {New SqlParameter("@cardno", recharge.cardno),
                                           New SqlParameter("@addmoney", recharge.addmoney),
                                           New SqlParameter("@gdate", recharge.gdate),
                                           New SqlParameter("@gtime", recharge.gtime),
                                           New SqlParameter("@userid", recharge.userid)}
        '向ReCharge_Info中插入充值记录
        <span style="background-color: rgb(51, 255, 255);">sql = "Insert into ReCharge_Info(CardNo,addmoney,gdate,gtime,UserID) Values(@cardno,@addmoney,@gdate,@gtime,@userid)"</span>
        flag1 = myHelper.AddDeleUpdate(sql, CommandType.Text, SqlParams)
        If flag1 = False Then
            flag = False
        Else
            '充值记录添加成功,更新Card_info中卡内金额
            Dim SqlParams1 As SqlParameter() = {New SqlParameter("@cardno", card.cardno),
                                          New SqlParameter("@cash", card.cash)}
            <span style="background-color: rgb(51, 255, 255);">sql = "update Card_info set [email protected] where [email protected]"</span>
            flag2 = myHelper.AddDeleUpdate(sql, CommandType.Text, SqlParams1)
            If flag2 = False Then
                flag = False
            Else
                flag = True
            End If
        End If</span>

使用存储过程

机房收费系统的下机功能(部分)实现需要执行两条SQL语句,下机成功后需要更新上下机记录表和卡表——相关代码(D层):

<span style="font-family:KaiTi_GB2312;font-size:18px;">Public Function offinsert(onoff As EOnoff) As Boolean Implements IOffline.offinsert
        Dim sql As String
        Dim card As New Entity.ECard
        Dim sqlParams As SqlParameter() = {New SqlParameter("@cardno", onoff.cardno),
                                           New SqlParameter("@offdate", onoff.offlinedate),
                                           New SqlParameter("@offtime", onoff.offlinetime),
                                           New SqlParameter("@consumetime", onoff.consumetime),
                                           New SqlParameter("@consumecash", onoff.consumecash),
                                           New SqlParameter("@ischeckout", "未结账"),
                                           New SqlParameter("@onoffstate", "下机")}
       <span style="background-color: rgb(51, 255, 255);"> sql = "PRO__offline"</span>
        Dim flag As Boolean
        flag = mysqlhelper.AddDeleUpdate(sql, <span style="background-color: rgb(51, 255, 255);">CommandType.StoredProcedur</span>e, sqlParams)

        Return flag
    End Function</span>

存储过程:PRO_offline

<span style="font-family:KaiTi_GB2312;font-size:18px;">USE [charge_sys]
GO
/****** Object:  StoredProcedure [dbo].[PRO__offline]    Script Date: 2016/5/27 17:07:29 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:<Tracy>
-- Create date: <2016/5/24>
-- Description:	<创建下机存储过程,更新上下机记录表和卡表>
-- =============================================
ALTER PROCEDURE [dbo].[PRO__offline]
	-- Add the parameters for the stored procedure here
	@cardno nvarchar(50),
	@offdate nvarchar(50),
	@offtime nvarchar(50),
	@consumetime nvarchar(50),
	@consumecash  numeric(18,1),

	@onoffstate nvarchar(50),
	@ischeckout nvarchar(50)
AS
BEGIN
	-- SET NOCOUNT ON added to prevent extra result sets from
	-- interfering with SELECT statements.
	SET NOCOUNT ON;

    -- Insert statements for procedure here
	<span style="background-color: rgb(51, 255, 255);">update</span> OnOff_Info  set [email protected] ,offlinetime [email protected],consumetime [email protected],consumecash [email protected] ,onoffstate  [email protected],ischeckout [email protected] where cardno [email protected]
	<span style="background-color: rgb(51, 255, 255);">update</span> Card_Info  set [email protected] where [email protected]
END</span>

【存储过程的优点】

⑴能实现模块化程序设计。存储过程是根据实际功能的需要创建的一个程序模块,并被存储在数据库中。以后用户要完成该功能,只要在程序中直接调用该存储过程即可,无需再编写重复的程序代码。存储过程可由数据库编程方面的专门人员创建,并可独立于程序源代码而进行修改和扩展。

⑵ 提高执行效率。当客户程序需要访问服务器上的数据时,一般要经过5个步骤:查询语句被发送到服务器→服务器编译T-SQL语句→优化产生查询执行计划→数据库引擎执行查询→执行结果发回客户程序,如果执行存储在客户端本地的T-SQL程序,那么每次执行该程序是,对于程序中的每一条语句都要经过以上5个步骤;而存储过程在创建时就被编译和优化,当存储过程第一次被执行时,SQL Server为其产生查询计划并将其保存在内存中,这样以后再调用该存储过程是就不必再进行编译,即以上5个步骤中的第2步和第3步就被省略了,这能大大改善系统的性能。

⑶增强了SQL的功能和灵活性。存储过程可以用流程控制语句编写,有很强的灵活性,能完成复杂的逻辑判断和复杂的运算。

⑷降低网络的通信量。一个需要数百行T-SQL代码的操作,如果将其创建成存储过程,那么使用一条调用存储过程的语句就可完成该操作,这样就避免了在网络上发送数百行代码,从而减少了网络负荷。

⑸减轻了程序编写的工作量。存储过程可以反复调用,并可供其他前端应用程序共享应用逻辑。

⑹间接实现安全控制功能。管理员可以不授予用户访问存储过程中涉及的表的权限,而只授予执行存储过程的权限,这样,既可以保证用户通过存储过程操纵数据库中的数据,由可以保证用户不能直接访问存储过程中涉及的表。用户通过存储过程来访问表,所能进行的操作是有限制的,从而保证了表中数据的安全性。

【存储过程的缺点】

⑴可移植性差

如果一个系统过多的使用了存储过程,那系统的业务逻辑过于依赖数据库,这样就会给系统额外的增加一层数据库中的业务逻辑层,如果开发的时候用的sql server,后来发现数据量过大,需要提高性能移植到oracle或者mysql,这样就会很麻烦,相当于把存储过程重写一遍,这是不能忍受的。

⑵性能扩展性问题

随着系统访问量的增长,系统必须进行不断地升级扩展,特别对于大型系统而言,更重要的是性能可扩展性而不是局部的性能。

处理逻辑如果全部放在存储过程里,所有的处理都在数据库服务器上进行,消耗的就是数据库服务器的CPU资源,大家知道数据库服务器由于需要较高的可靠性,通常选用的都是价格昂贵的服务器,对数据库服务器升级通常都花费很大。

如果把处理逻辑放在中间层服务器上进行,中间层服务器一般都是小型的机器,价格便宜,而且中间层服务器的CPU通常主频比数据库服务器的速度还快(比如现在8CPU的数据库服务器主频只有800M,而双CPU的刀片式服务器CPU主频已经到2.8G了),而且对于多层架构,支持中间层服务器可以增加多台机器进行负载均衡,用中间层服务器即价格便宜,扩展空间也更大。

⑶代码可复用性差

存储过程还是过程型语言,两个很相似的功能在也需要两个存储过程,因为他们是互相独立的,可以互相调用,但是不能继承等面向对象的操作,这也就增加了代码量。

【小结】

1、存储过程的使用有利有弊,我们应该根据实际情况来确定是否用存储过程,存储过程应该有选择地使用,牵涉到批量数据操作的,用存储过程较好。对于小数据量处理的事务操作,应放到中间层处理,这样系统的移植性和扩展性更好。

2、不要陷入“业务应该跟着技术走”的误区,刚开始不会用存储过程,基本数据设定表中更新记录的时候只是一条Update语句就使用了存储过程,有点本末倒置,应该是为了优化系统,实现业务而运用技术,仅仅一条sql语句其实没有必要用存储过程。

3、之前跟师傅交流提到过存储过程,我了解到的全部都是存储过程的优点,师傅强调了一下它的缺点,还有触发器(特殊的存储过程),忽然觉得对于知识的学习应该由点及面,一点点拓展,一点点深入,对知识的学习不满足,保持恒久的求知欲。

不足之处,请大家多多提意见~~

时间: 2024-10-11 00:21:23

【机房重构】——存储过程(Stored Procedure)的相关文章

机房重构——存储过程

原来只是见过存储过程这几个字,知道有这么一个东西,但并未真正揭开它的面纱去真正了解它,但是在敲机房的时候就遇到了难题,要修改数据库中多张表的数据,使用SQL语句的话会很复杂,究竟什么可以让我们的效率提高呢?存储过程可以做到,这就迫使我不得不去再次触碰存储过程. 定义:在大型数据库中,一组完成特定功能SQL语句的集合.相当于就是将原本需要再D层多次写的SQL语句,在数据库中写到了一块. 何时才会用到存储过程,我们从定义中就能看出存储过程是SQL语句的集合,当我们使用的SQL语句复杂时,使用存储过程

SQL Server中存储过程Stored Procedure创建及C#调用

存储过程就是已经编译好的.优化过的放在数据库服务器中的一些SQL语句:可供应用程序直接调用.使用存储过程有以下几个优点: 1.执行速度比普通的SQL语句快 2.便于集中控制 3.可以降低网络的通信量 4.保证数据库的安全性和完整性 5.灵活性 创建存储过程 可以采用Transact-SQL语句来创建存储过程Stored Procedured.在Microsoft SQL Server Management Studio中Databases->Database Name->Programmabi

Stored Procedure 里的 WITH RECOMPILE 到底是干麻的?

原文:Stored Procedure 里的 WITH RECOMPILE 到底是干麻的? 在 SQL Server 创建或修改「存储过程(stored procedure)」时,可加上 WITH RECOMPILE 选项,但多数文档或书籍都写得语焉不详,或只解释为「每次执行此存储过程时,都要重新编译」.事实上,是指执行此一存储过程时,要强制重新产生「执行计划(execution plan)」,而不要从「缓存(cache)」去取得旧的「执行计划」. SQL Server 在评估与产生「执行计划」

【机房重构】SQl之存储过程

上篇博客介绍了SQl视图的使用,这篇博客通过内容和实例应用来简单介绍一下存储过程. 在机房重构的过程中,犯了个大忌(数据库设计在重构过程被修改了),所以影响了一个功能的实现,就又重新敲了一下机房收费系统退卡功能.正如"塞翁失马,焉知非福",纯三层的代码实现变成了利用存储过程之后的完美实现.期间的磕磕绊绊都让我们对存储过程加深了理解. 存储过程: 定义: 当需要写多条SQl语句的时候,就可以使用存储过程,在数据库中建立存储过程.之后在VS中通过调用存储过程来使用. 百度百科:存储过程(S

vb.net机房收费系统重构——存储过程的使用

在敲写七层登陆过程中,接触了存储过程的概念,但当时还没使用.在正式的重构过程中,一点点添加,将存储过程也添加到了重构中.才正式了解了存储过程. 首先 [存储过程的概念] 存储过程Procedure是一组为了完成特定功能的SQL语句集合,经编译后存储在数据库中,用户通过指定存储过程的名称并给出参数来执行. 存储过程中可以包含逻辑控制语句和数据操纵语句,它可以接受参数.输出参数.返回单个或多个结果集以及返回值. [存储过程的使用] 首先,打开数据库--存储过程 右键-新建存储过程 CREATE PR

机房重构(3)——存储过程

在敲机房收费过程中我们都会遇到这样的问题:很多功能实现都需要涉及到多张表的操作,比如充值.退卡.结账等功能的实现.这就需要我们多次对数据库进行操作,不仅代码量大大增加,而且执行效率也会大打折扣.为了提高效率,于是,存储过程就华丽登场了. 1.简介 存储过程是一组为了完成特定功能的语句集,经过编译后存储在数据库中,用户通过制定存储过程的名称并给出参数来执行它.存储过程在运算时生成执行方式并存储在数据库当中,当其再次运行时速度比单个的SQL语句要快.    2.优缺点 1)优点 a.复用性强.存储过

【机房重构】—存储过程当媒人

以下是本人亲眼所见的机房重构帅小伙(简称重构),借助存储过程媒人(简称存储)与数据库大美女(简称:库)交往的经历,和大家分享一下. 那是一个风和日丽的白天,重构帅小伙独自一人走在处处飘香的初夏的校园中,他一直在思考,如何与库美女更容易的交往呢?以前重构去找库美女的时候总是需要先打一个电话(链接一个表),再问问库美女在哪里(再链接一个表),然后才能去找库美女(向两个表中存入数据):重构绞尽脑汁终于想出了一个办法, 他通过手机中的GPS(存储过程)直接定位库美女的位置,然后突然给库美女一个惊喜,这样

SQL Server 在多个数据库中创建同一个存储过程(Create Same Stored Procedure in All Databases)

原文:SQL Server 在多个数据库中创建同一个存储过程(Create Same Stored Procedure in All Databases) 一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 遇到的问题(Problems) 实现代码(SQL Codes) 方法一:拼接SQL: 方法二:调用模板存储过程创建存储过程: 总结 扩展阅读 参考文献(References) 二.背景(Contexts) 在我的数据库服务器上,同一个实例

数据库术语之存储过程(Stored Procedure)

存储过程(Stored Procedure,以下简称SP)是啥?有什么用?优缺点? 一个SP是一段存储在数据库中的sql语句,它能被触发器,或者其他的SP以及APP触发. 直观看来,就像是数据库中的自定义函数,navicat直接将其列在了函数类别里: 未完待续... 参考文章: [1]数据库存储过程 by yang3wei