博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

第11章 存储过程

Posted on 2010-07-21 10:20  Jeffrey mao  阅读(141)  评论(0)    收藏  举报

11. 存储过程

本章主题

l        什么是存储过程

l        创建存储过程

l        细说CREATE PROCEDURE命令

l        嵌套存储过程

l        执行存储过程

l        重命名存储过程

l        修改存储过程

l        删除存储过程

l        重新编译存储过程

 

必杀技! 不可不学!学习如何使用SQL来写stored procedure

 

11.1. 什么是存储过程

经过前四章的洗礼,相信您对MicrosoftSQL Server2000程序设计已有了基本的认识。

第07章Transact-SQL程序设计

第08章 数据的查询、汇总 、统计和分析

第09章 添加、修改和删除数据记录

第10章 视图

 

本章开始更高级的内容。

 

存储过程包含一些Transact-SQL语句,并以特定的名称存储在数据库中。存储过程是一种数据库对象。可以在存储过程中声明变量、有条件执行以及其他各项强大的程序设计功能。

l       它能够包含执行各项数据库操作的语句,并且可以调用其他的存储过程。

l       能够接收输入参数并以输出参数的形式将多个数据值返回给调用程序。

具体示例:试着看看,看得懂吗?后面会详介

CREATE  PROCEDURE getPerson @mName varchar(10)@mCur_salarymoney

AS

UPDATEvfpman

SETcur_salary= cur_salary*1.2

WHEREname=@mName AND cur_salary=@mCur_salary

 

11.1.1. 存储过程的优点

l       允许模块化程序设计

l       更快的执行速度,存储过程被预先编译和优化并存储在数据库中

l       有效降低网络流量

l       较好的安全,如限制某人对某个表操作,却又必须要求他对该表执行特定的操作。

 

11.2. 创建存储过程

使用企业管理器

 

CREATE PROCEDURE命令

在查询分析器中执行命令。

 

11.3. 细说CREATEPROCEDURE命令

CREATE  PROC [ EDURE ]  procedure_name [ ; number ]

[ { @parameter data_type }

        [ VARYING ] [ = default ] [ OUTPUT ]

    ] [ ,...n ]

[ WITH

    { RECOMPILE |ENCRYPTION | RECOMPILE , ENCRYPTION } ]

[ FOR REPLICATION ]

AS sql_statement [ ...n ]

 

;number

是可选的整数,用来对同名的过程分组,以便用一条 DROP PROCEDURE 语句即可将同组的过程一起除去。例如,名为 orders 的应用程序使用的过程可以命名为 orderproc;1、orderproc;2等。DROP PROCEDUREorderproc 语句将除去整个组。

 

VARYING

指定作为输出参数支持的结果集(由存储过程动态构造,内容可以变化)。仅适用于游标参数。

 

11.3.1. 指定存储过程的名称

l       存储过程名称最长不超过128字符

l       为避免与系统存储过程相混淆,尽量不要以sp_开头

 

11.3.2. 指定存储过程的语句

CREATE PROCEDURE命令不能够与其他的Transact-SQL命令位于同一个批处理中。

下面的代码会出错:

USE NorthwindSQL      --与下面的CREATE PROCEDURE在同一批处理中

CREATE PROCEDURE myproc

AS

  SELECT * FROM 飞狐工作室

 

修改为:

USE NorthwindSQL      

GO

CREATE PROCEDURE myproc

AS

  SELECT * FROM 飞狐工作室

 

注解:

l       每一个存储过程最好只负责完成一项工作

l       一个狠好的建议:在创建存储过程前,先在SQL查询分析器中编写并测试要包含在存储过程中的程序代码,等一切无误后,再加入CREATEPROCEDURE命令将它创建成存储过程。

l       存储过程可以访问表、视图,并可以调用其它存储过程。

l       存储过程的最大长度是128MB(其实不太可能达到这个长度的)

11.3.3. 输入参数

将数据值传递给存储过程,该数据值也称为输入参数。

{ @parameter data_type }

        [VARYING ] [ = default ] [ OUTPUT ]

l       参数的名称必须以@开头。

l       data_type指定输入参数的数据类型。

l       default用来指定输入参数的默认值。

l       一个存储过程最多可以拥有2100个参数(包括输入参数和输出参数)。

 

范例一:利用传入的参数选出选定的姓名的员工资料。

/*档案名称: Demo111.sql */

USE NorthwindSQL

IF EXISTS (SELECT name FROM sysobjects

         WHERE name ='DemoProc1' AND type = 'P')

   DROP PROCEDURE DemoProc1

GO

 

CREATE PROCEDURE DemoProc1

     @name varchar(10)

AS

SELECT 身份证字号,

        姓名,

        出生日期,

        年龄= DATEDIFF(yy,出生日期,GETDATE())

   FROM 飞狐工作室

   WHERE 姓名  = @name

GO

 

执行该存储过程:

EXECUTE DemoProc1 ‘许建仁’  --方法之一

EXECUTE DemoProc1 @name=‘许建仁’  --方法之二

--参数名一定要与定义时的名称一致

--您更喜欢哪一种方法?

 

范例二:

/*档案名称: Demo112.sql */

USE NorthwindSQL

IF EXISTS (SELECT name FROM sysobjects

         WHERE name ='DemoProc2' AND type = 'P')

   DROP PROCEDURE DemoProc2

GO

 

CREATE PROCEDURE DemoProc2

     @BeginningDatedatetime = '01/01/1900',

     @EndingDatedatetime = '12/31/2001'

AS

SELECT a.客户编号,a.公司名称,

       a.地址,a.连络人,a.电话,

       b.订单号码,b.订单日期,

       b.运费,b.收货人,

       c.产品编号,c.单价,

       c.数量,c.折扣

  FROM 客户a INNER JOIN 订货主档 b

             INNER JOIN 订货明细c

             ON b.订单号码= c.订单号码

             ON a.客户编号= b.客户编号

  WHERE

      b.订单日期BETWEEN @BeginningDate AND @EndingDate

GO

 

执行该存储过程:

EXECUTE DemoProc2 ‘07/01/1996’,’07/31/1996’

EXECUTEDemoProc2 @BeginningDate =‘07/01/1996’,

@EndingDate=’07/31/1996

--参数名一定要与定义时的名称一致

 

范例三:该范例体现了一种技巧!

/*档案名称: Demo113.sql */

USE NorthwindSQL

IF EXISTS (SELECT name FROM sysobjects

         WHERE name ='DemoProc3' AND type = 'P')

   DROP PROCEDURE DemoProc3

GO

 

CREATE PROCEDURE DemoProc3

     @id varchar(10) = '[A-M]%',

     @name varchar(10) = '许%',

     @address varchar(10)= '%台北市%'

AS

SELECT *  FROM 飞狐工作室

   WHERE

       身份证字号LIKE @id AND

       姓名LIKE @name AND

       住址LIKE @address

GO

执行该存储过程:

EXECUTE DemoProc3 ‘ALM]%’, ’_正_’,  ‘%锦州市%’

EXECUTE DemoProc3

 

 

 

11.3.4. 输出参数

范例一:示范将传入参数相乘后将结果返回。

/*档案名称: Demo114.sql */

USE NorthwindSQL

IF EXISTS (SELECT name FROM sysobjects

         WHERE name ='DemoProc4' AND type = 'P')

   DROP PROCEDURE DemoProc4

GO

 

CREATE PROCEDUREdbo.DemoProc4

     @mult1 int,

     @mult2 int,

     @result int  OUTPUT

AS

SET@result = @mult1 * @mult2

GO

 

执行该存储过程:

/*档案名称: Demo115.sql */

USE NorthwindSQL

DECLARE @answer int

EXEC DemoProc4 12,33, @answerOUTPUT

SELECT '运算结果是: ',@answer

 

范例二:计算出指定部门的平均薪资、最大薪资和最低薪资。

/*档案名称: Demo116.sql */

USE NorthwindSQL

 

IF EXISTS (SELECT name FROM sysobjects

         WHERE name ='DemoProc5' AND type = 'P')

   DROP PROCEDURE DemoProc5

GO

 

CREATE PROCEDUREdbo.DemoProc5

     @department varchar(10),

     @average money  OUTPUT,

     @maximum money  OUTPUT,

     @minimum money  OUTPUT

AS

SELECT@average = AVG(目前薪资),

                @maximum = MAX(目前薪资),

                @minimum = MIN(目前薪资)

     FROM 飞狐工作室

     WHERE 部门= @department

GO

 

执行该存储过程:

/*档案名称: Demo117.sql */

USE NorthwindSQL

DECLARE @department varchar(10)

DECLARE @average decimal(19,4)

DECLARE @maximum decimal(19,4)

DECLARE @minimum decimal(19,4)

SELECT @department = '生产制造部'

 

EXEC DemoProc5 @department,

                                @average OUTPUT,

                                @maximum OUTPUT,

                                @minimum OUTPUT

 

SELECT '平均薪资:'+CONVERT(nvarchar,@average),

                '最高薪资:'+CONVERT(nvarchar,@maximum),

                '最低薪资:'+CONVERT(nvarchar,@minimum)

 

11.4. 嵌套存储过程

存储过程的嵌套---存储过程中调用其他的存储过程。

嵌套最高可达32层。

被调用的存储过程将可访问调用它的存储过程中所创建的所有对象。

 

11.5. 执行存储过程

l       可以在存储过程中使用RETURN命令将一个整数返回到调用程序、批处理或存储过程。

l       如果并未在RETURN命令中指定返回值,默认将返回数值0。

 

范例一:检查用户所指定的姓名是否存在于“飞狐工作室”表,如果存在,则返回1,如果不存在,则返回2

/*档案名称: Demo118.sql */

USE NorthwindSQL

 

IF EXISTS (SELECT name FROM sysobjects

         WHERE name ='checkname' AND type = 'P')

   DROP PROCEDURE checkname

 

GO

 

CREATE PROCEDURE checkname@EmployeeName varchar(10)

AS

IF (SELECT count(*) FROM 飞狐工作室 WHERE 姓名 = @EmployeeName) > 0

   RETURN 1

ELSE

   RETURN 2

 

GO

 

执行该存储过程:

/*档案名称: Demo119.sql */

DECLARE @RC int

EXEC @RC = checkname  '章立民'

IF @RC = 1

    PRINT '存在'

ELSE

    PRINT '不存在'

 

11.5.1. INSERTINTO …EXECUTE

如果存储过程中以SELECT命令返回查询结果,则可以使用INSERT命令将存储过程所返回的查询结果添加到一个表中。

INSERT INTO 表名 EXEC 存储过程名

 

范例一:示范将存储过程的查询结果添加到一个表中。

/*档案名称: Demo1110.sql */

USE NorthwindSQL

IF EXISTS (SELECT name FROM sysobjects

         WHERE name ='SalaryOverview' AND type = 'P')

   DROP PROCEDURE SalaryOverview

GO

 

CREATE PROCEDURESalaryOverview

AS

SELECT 部门,

       性别= CASE 性别

               WHEN 0 THEN '女'

               WHEN 1 THEN '男'

             END,

       婚姻状况= CASE 婚姻状况

                   WHEN 0 THEN '未婚'

                   WHEN 1 THEN '已婚'

                 END,         

       最低薪资= MIN(目前薪资),

       最高薪资= MAX(目前薪资),

       平均薪资= AVG(目前薪资)

  FROM 飞狐工作室

  GROUP BY 部门,

           CASE 性别

             WHEN 0 THEN '女'

             WHEN 1 THEN '男'

           END,

           CASE 婚姻状况

             WHEN 0 THEN '未婚'

             WHEN 1 THEN '已婚'

           END

 

GO

 

执行该存储过程:

/*档案名称: Demo1111.sql */

USE NorthwindSQL

--将预存程序 SalaryOverview 所传回的结果新增至表 IncomeOverview

--IncomeOverview表应该已经存在

INSERT INTO IncomeOverview EXEC SalaryOverview

 

SELECT * FROM IncomeOverview

 

11.6. 重命名存储过程

特别提醒:除非必要,不要随便更改存储过程的名字,原因是这样会造成许多与存储过程依附的对象找不到存储过程而产生错误。

 

11.6.1. 使用SQL Server企业管理器

 

11.6.2. 使用系统存储过程sp_rename

EXEC sp_rename‘GetTopSales’, ‘TopSales’

 

11.7. 修改存储过程

11.7.1. 使用SQL Server企业管理器

“存储过程属性”对话框,但此时不可以修改CREATEPROCEDURE后的存储过程名称。

11.7.2. 使用查询分析器

11.8. 删除存储过程

11.8.1. 使用SQL Server企业管理器

 

11.8.2. 使用DROP PROCEDURE命令

DROPPROCEDURE 存储过程名

 

第11章 结束