存储过程

文章导航 SQL Server 2005 学习笔记系列文章导航

 

在写这一系列的文章的时候发现有些朋友,还有就是我的同事们,对数据的基本类型和基本操作上不是很熟悉,像存储过程 ,事务这些东西不怎么理解,

我就本着帮助新手的理念在这里把这一系列的东东都 一个一个的介绍一下吧,里面再加上一个例子,相信可以对他们有些帮助。新手学习,高手指点吧,呵呵

 

介绍          


 

   我们先来了解一下什么是存储过程吧,存储过程是由流控制和SQL语句书写的过程,这个过程经编译和优化后存储在数据库服务器中,应用程序使用时只要调用即可。在ORACLE中,若干个有联系的过程可以组合在一起构成程序包。

  存储过程是利用SQL Server所提供的Transact-SQL语言所编写的程序。Transact-SQL语言是SQL Server提供专为设计数据库应用程序的语言,它是应用程序和SQL Server数据库间的主要程序式设计界面。它好比Oracle数据库系统中的PL-SQL和Informix的数据库系统结构中的Informix- 4GL语言。这类语言主要提供以下功能,让用户可以设计出符合引用需求的程序:

  1)、变量说明

  2)、ANSI兼容的SQL命令(如Select,Update….)

  3)、一般流程控制命令(if…else…、while….)

  4)、内部函数

  存储过程(Stored Procedure)是一组为了完成特定功能的SQL 语句集,经编译后存储在数据库中。用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。

  存储过程可由应用程序通过一个调用来执行,而且允许用户声明变量 。同时,存储过程可以接收和输出参数、返回执行存储过程的状态值,也可以嵌套调用。

 

它的优点

 


 

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

  * 可保证数据的安全性和完整性。

  # 通过存储过程可以使没有权限的用户在控制之下间接地存取数据库,从而保证数据的安全。

  # 通过存储过程可以使相关的动作在一起发生,从而可以维护数据库的完整性。

  * 在运行存储过程前,数据库已对其进行了语法和句法分析,并给出了优化执行方案。这种已经编译好的过程可极大地改善SQL语句的性能。由于执行SQL语句的大部分工作已经完成,所以存储过程能以极快的速度执行。

  * 可以降低网络的通信量。

  * 使体现企业规则的运算程序放入数据库服务器中,以便 集中控制。

  # 当企业规则发生变化时在服务器中改变存储过程即可,无须修改任何应用程序。企业规则的特点是要经常变化,如果把体现企业规则的运算程序放入应用程序中,则当企业规则发生变化时,就需要修改应用程序工作量非常之大(修改、发行和安装应用程序)。如果把体现企业规则的运算放入存储过程中,则当企业规则发生变化时,只要修改存储过程就可以了,应用程序无须任何变化。

 

分类

 


 

   1)、系统存储过程:以sp_开头,用来进行系统的各项设定.取得信息.相关管理工作,

  如 sp_help就是取得指定对象的相关信息,sp_refreshview 是刷新视图

  2)、扩展存储过程以XP_开头,用来调用操作系统提供的功能

  exec master..xp_cmdshell 'ping 10.8.16.1'

  3)、用户自定义的存储过程,这是我们所指的存储过程

 

存储过程的格式

 


 

    CREATE PROCEDURE [拥有者.]存储过程名[;程序编号]

  [(参数#1,…参数#1024)]

  [WITH

  {RECOMPILE | ENCRYPTION | RECOMPILE, ENCRYPTION}

  ]

  [FOR REPLICATION]

  AS 程序行

  其中存储过程名不能超过128个字。每个存储过程中最多设定1024个参数

  (SQL Server 7.0以上版本),参数的使用方法如下:

  @参数名 数据类型 [VARYING] [=内定值] [OUTPUT]

  每个参数名前要有一个“@”符号,每一个存储过程的参数仅为该程序内部使用,参数的类型除了IMAGE外,其他SQL Server所支持的数据类型都可使用。

  [=内定值]相当于我们在建立数据库时设定一个字段的默认值,这里是为这个参数设定默认值。[OUTPUT]是用来指定该参数是既有输入又有输出值的,也就是在调用了这个存储过程时,如果所指定的参数值是我们需要输入的参数,同时也需要在结果中输出的,则该项必须为OUTPUT,而如果只是做输出参数用,可以用CURSOR,同时在使用该参数时,必须指定VARYING和OUTPUT这两个语句。

       

例子

 


 

    我们一起来看几个例子吧,先来看一下最简单的一个,我们现在要做的工作是查询表City中的所有数据

  看代码

 

代码

SET  ANSI_NULLS  ON
GO
SET  QUOTED_IDENTIFIER  ON
GO
--  =============================================
--
 Author:        <Author,sufei>
--
 Create date: <Create Date,2010-09-03>
--
 Description:    <Description,查询表City的所有信息>
--
 =============================================
CREATE   PROCEDURE  IP_selectAllCity
AS
BEGIN
    
SELECT   *   FROM  City
END
GO

--  exec IP_selectAllCity

 

   执行的结果如下图

    

 这个是很简单了,下面我们一起分析一个复杂一点的

 

代码
set  ANSI_NULLS  ON
set  QUOTED_IDENTIFIER  ON
go
--  =============================================
--
 Author:        <Author,,sufei>
--
 Create date: <Create Date,2010-02-01 2:42>
--
 Description:    <Description,财务端用来查询各商户各业务的总交易量>
--
 =============================================
ALTER    proc   [ dbo ] . [ PGetSaleTableInfo1 ]
@st   as   DateTime   =   ' 2009-07-01 ' ,
@et   as   DateTime   =   ' 2009-07-20 '
AS

select  t1. * ,  t2.ofLogin  as  ofName, t3.fiName  from  
(  
-- 移动
select  ormOid  as  offId, ormType  as  funid, cast ( sum (ormPayAmount)  AS   decimal ( 18 , 2 ))   as  amountsum  from  ordermobile 
where  ormState  in  ( 2 , 6 and  ormExecTime  >=   @st   and  ormExecTime <= @et   group   by  ormOid, ormType
union   -- 联通
select  oruOid  as  offId, oruType  as  funid, cast ( sum (oruPayAmount)  AS   decimal ( 18 , 2 ))   as  amountsum  from  orderunicom 
where  oruState  in  ( 2 , 6 and   oruExecTime  >=   @st   and  oruExecTime <= @et   group   by  oruOid, oruType
union   -- 电信
select  ortOid  as  offId, ortType  as  funid, cast ( sum (ortPayAmount)  AS   decimal ( 18 , 2 ))   as  amountsum  from  ordertelecom
where  ortState  in  ( 2 , 6 and   ortExecTime  >=   @st   and  ortExecTime <= @et   group   by  ortOid, ortType
as  t1, 
officeInfo 
as  t2, functionInfo  as  t3  where  t1.offId  =  t2.ofId  and  t1.funid  =  t3.fiId
order   by  ofName   

-- exec PGetSaleTableInfo1  '2010-01-01','2010-03-25'

 

     我们来一起分析一下这个存储过程吧,存储过程的作用是查询出来ordermobile (中国移动缴费记录)  orderunicom(中国联通缴费记录) ordertelecom

(中国电信缴费记录)三张表,在一段时间内,各个用户,各个业务的缴费总各。@st as DateTime = '2009-07-01',
@et as DateTime = '2009-07-20'  这是两个时间参数,@st开始时间,@et结束时间。我是利用 Select Union的方式把三个表合并在了一起,然后按用户ID,和业务ID分了一下组,并使用cast(sum(ortPayAmount) AS decimal(18,2))  as amountsum 这一句来得到所有这个用户某个业务的交易总各的sum是求和大家都知道了cast带有四舍五入的功能。

      执行一下存储过程我们一起来看一下结果吧

这样的话我们就把每一个用户的每一个业务的交易总各查了出来了。

 

c#调用Sql2005的存储过程

 


现在我们使用c#来调用 一下这个存储过程吧,我在这里使用SqlHelper 类

 

代码
    ///   <summary>
        
///  财务端用来查询各业务的总交易量
        
///   </summary>
        
///   <param name="startTime"> 开始时间 </param>
        
///   <param name="endtime"> 结束时间 </param>
        
///   <returns> DataTable </returns>
         public  DataTable PGetSaleTableInfo1(DateTime startTime, DateTime endtime)
        {
            SqlParameter[] parameters 
=  {
                   
new  SqlParameter( " @sdt  " , SqlDbType.DateTime),
                    
new  SqlParameter( " @edt " , SqlDbType.DateTime)};
            parameters[
0 ].Value  =  startTime;
            parameters[
1 ].Value  =  endtime;
            
return  SqlHelper.GetTableProducts( " PGetSaleTableInfo1 " , parameters)[ 0 ];
        }

 


我们要以传进去两个时间就可以了。前台查询得到的效果如下

  当然,这是经过我处理过后的结果,我是把业务当成了列,并且在单击每一个金额是能查出相应的来源,

在这里我可以简单的提供一下思路,如果有朋友对这一块感兴趣的话,咱们可以交流一下的

  我可以把我是怎么样生成这个表的代码放在这里,

 

 

       //在这里扩展新业务  大家在扩展的时候只要看到这一行字,在下面接着增加新业务就是了,只要能得到这个表,我相信下面的统计,什么的应该都很简单了吧,只要一个枚举类统计一下各个业务的和就是了,呵呵

      接着来看存储过程

下面我们再来看一下分页的存储过程吧,在Sql2005里有了row_number()函数我们处理分页就显的非常的简单了

看下代码吧

 

                         

         欢迎大家转载,如有转载请注明文章来自:   http://sufei.cnblogs.com/   

签名:做一番一生引以为豪的事业;在有生之年报答帮过我的人;并有能力帮助需要帮助的人;    

QQ:361983679 Email:sufei.1013@163.com  MSN:sufei.1013@163.com 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值