文章导航 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 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>
/// <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