您的位置:首页 - 教程 - Sql Server - 正文
SQL Server 数据库的维护(一)__存储过程(procedure)

--维护数据库--



--存储过程(procedure)--

--概述
  SQl Serve的存储过程是由一个或多个T-SQL语句组成的一个集合。常用的程序代码段通常被创建成存储过程,一次创建多次调用,这样既简化程序员的工作也减少与服务器交互的网络通信流量。存储过程中可以包含数据库中执行操作的程序语句,也包括调用其他过程。存储过程可以接收和输出参数,向调用它的程序返回值。存储过程被调用后,会返回给调用它的程序状态值,以表明调用成功或者调用失败以及调用失败的原因。
--使用存储过程的优点
1)减少网络流量在客户端和服务器的交互中,T-SQL语言中的每个代码行在执行时都是要利用网络发送的,代码被封装成存储过程,只有对执行存储过程语句的调用时才会利用网络发送
2)增强安全性在客户端和服务器之间调用存储过程时,只有执行存储过程的语句是可见的,用户无法看到或访问到存储过程所涉及的数据库对象,便无法破坏这些对象,使用为存储过程加密也能保障存储过程的安全。
3)提升编程效率。存储过程对常用代码的封装采用了消除重复代码的编写操作,降低代码的不一致性,并允许拥有权限的用户访问和执行代码,提升代码编程效率。
4)提高执行效率。系统默认下,只有首次执行存储过程时需要编译存储过程,创建一个执行计划,今后在执行该存储过程时则无需在编译,节省程序处理时间,提高执行效率。如果存储过程引用的数据发生变化明,也无需重新编写存储过程,系统提供了重新编译存储过程来帮助存储过程正确执行。
--分类:(在SQL Server 中存储过程分为用户自定义存储过程系统存储过程拓展存储过程三种类型)
1)用户自定义存储过程该存储过程封装了用户所需的功能代码,可以单纯实现一段程序代码,可以通过输入参数接收用户输入的值(带输入参数的存储过程),可以使用输出参数将存储过程执行后的结果返回给调用它的语句(带输出参数的存储过程)。
2)系统存储过程以sp_开头的存储过程是系统存储过程。是系统封装好的程序代码。例如:sp_helptext表示查看数据库对象信息;sp_helpindex表示查看表中索引信息。
3)拓展存储过程以xp_开头的存储过程是拓展存储过程。由系统提供,用来在SQL Server和外部程序之间提供一个接口,以实现各种系统的维护活动。例如:xp_loogininfo表示返回Windows用户和Windows组的相关信息。
--存储过程管理
--存储过程的创建和执行(注:创建存储过程的语句要存在于同一个批处理中。)
  --不带参数的存储过程
  ♦创建:
create procedure 存储过程名 --create procedure命令表示创建存储过程,procedure允许只写前四个字母proc。
[with encryption] --with encryption是可选项,可以为存储过程的创建文本加密。
[with recompile] --with recompile是可选项,使存储过程在执行时不保存执行计划,在每次执行时重新编译,以防止覆盖已存在于内存中的执行计划。
as
T-SQL语句

例:(创建名为“p_客户信息表_地址”的存储过程,用来实现在“商品管理数据库”的“客户信息表”中查询“辽宁沈阳”的客户信息)
use 商品管理数据库
go
select*from 客户信息表 where 地址='辽宁沈阳' --创建前可以先查询一下要封装的记录

use 商品管理数据库
go
create proc p_客户信息表_地址 --创建存储过程
as
select*from 客户信息表 where 地址='辽宁沈阳'

  ♦执行:
execute 存储过程名 --execute表示执行存储过程,可以简写exec。

例:
use 商品管理数据库
go
exec p_客户信息表_地址

  --带参数的存储过程(带输入参数的存储过程 和 带输出参数的存储过程)
    --1)带输入参数的存储过程
    ♦创建:
create procedure 存储过程名 --create procedure命令表示创建存储过程,procedure允许只写前四个字母proc。
@参数名 数据类型[(长度)] [, ......] --参数名,应声明在as之前
[with encryption] --with encryption是可选项,可以为存储过程的创建文本加密。
[with recompile] --with recompile是可选项,是存储过程在执行时不保存执行计划,在每次执行时重新编译,以防止覆盖已存在于内存中的执行计划。
as
T-SQL语句

例:(创建名为“p_客户信息表_地址x”的存储过程,用来实现在“商品管理数据库”的“客户信息表”中查找指定地址的客户信息)
use 商品管理数据库
go
create proc p_客户信息表_地址x
@address nvarchar(30)
as
select*from 客户信息表 where 地址=@address  

    ♦执行:
execute 存储过程名 [@参数名=] 参数值 [, ...] --“参数值”的数据类型必须与被赋值参数的数据类型兼容

例:(执行存储过程“P_客户信息表_地址x”,查找出地址“辽宁沈阳”的客户信息)
use 商品管理数据库
go
exec p_客户信息表_地址x @address='辽宁沈阳'
exec p_客户信息表_地址x '辽宁大连' --省略参数名

    --2)带输出参数的存储过程
    ♦创建:
create procedure 存储过程名 --create procedure命令表示创建存储过程,procedure允许只写前四个字母proc。
[@参数名 数据类型[(长度)][ , ...... , ] ]
@参数名 数据类型[(长度)] output [ , ...... ]
[with encryption]
[with recompile]
as
T-SQl语句
--允许创建只带输入参数的存储过程,也允许创建既带输出参数又带输入参数的存储过程。输出参数要在声明参数后加上output关键字来指明。通常再被封装在存储过程中的T-SQL语句中为输出参数赋值。

例:(创建名为“p_客户信息表_姓名”的存储过程,将查询“客户信息表”中客户编号为20130001的客户信息姓名,并将客户姓名赋值给一个输出参数的查询代码封装到该存储过程中)
create proc p_客户信息表_姓名
@name nvarchar(5) output
as
set @name=(select 客户姓名 from 客户信息表 where 客户编号='20130001')
--select @name=客户姓名 from 客户信息表 where 客户编号='20130001'

    ♦执行:
declare @参数名 数据类型[(长度)][, ...] --首先使用declare命令声明执行过程中所涉及的参数,包括输入参数和输出参数
[set @参数=值1] ... --如果使用了输入参数,用set语句为输入参数赋值
execute 存储过程名 [@参数[, ... ,]] @参数 output [, ...]

例:(执行名为“p_客户信息表_姓名”的存储过程,要求将查询“客户信息表”中的客户编号为20130001的客户姓名显示出来)
use 商品管理数据库
go
declare @name nvarchar(5)
exec p_客户信息表_姓名 @name output
print '客户编号为20130001的客户姓名为:'+@name

例:带输入参数的存储过程、带输出参数的存储过程 的创建和执行的总例:(创建名为“p_客户信息表_编号_姓名”的存储过程,要求将查询“客户信息表”中指定客户编号的客户姓名显示出来。并执行存储过程查看结果)
create proc p_客户信息表_编号_姓名
@num nchar(8),@name nvarchar(5) output --定义了一个输入参数@num和一个输出参数@name,数据类型和取值范围与“客户信息表”中的“客户编号”字段和“客户姓名”字段一致
as
select @name=客户姓名 from 客户信息表 where 客户编号=@num

use 商品管理数据库
go
declare @num nchar(8),@name nvarchar(5) --定义了@num和@name两个用来与存储过程中的参数传递和接收值。
set @num='20130001' --使用set命令为变量@num赋值,以便将值传给输入参数@num。
exec p_客户信息表_编号_姓名 @num,@name output --exec执行存储过程时按顺序将两个变量带入到存储过程中。
print '客户编号为'+@num+'的客户的姓名为:'+@name --print语句使用了字符串连接运算,输出详细结果。
理解例子

 

--查看存储过程

注:可以使用系统存储过程sp_helptextsp_helpsp_depends查看存储过程的创建信息和创建文本。
exec 系统存储过程 用户自定义存储过程名
说明:sp_helptext显示被查看的存储过程的创建文本信息,创建时被加密的存储过程的创建文本信息不能被查看。
sp_help显示被查看的而存储过程的所有者类型创建时间包含哪些参数等信息。
sp_depends显示被查看的存储过程所关联的数据表和字段信息

例:
use 商品管理数据库
go
exec sp_depends p_客户信息表_姓名
exec sp_help p_客户信息表_姓名
exec sp_helptext p_客户信息表_姓名

--修改存储过程
注:在管理数据库过程中,可以根据需要修改已创建的用户自定义存储过程。对于已经加密的存储过程,不能使用管理器方式修改其内容,拥有权限的用户可以使用T-SQl语言修改其创建内容,同时将加密属性去掉,当实质上是删除原来的加密的存储过程,重新创建一个新的存储过程,使用时须谨慎使用。
alter procedure 存储过程名 ---alter命令表示修改,“存储过程名”必须是已存在的用户自定义的存储过程。procedure允许只写前四个字母proc。
[@参数名 数据类型[(长度)][, ... ,]] @参数名 数据类型[(长度)] output [, ......]
[with encryption]
[with recompile]
as
T-SQL语句

例:(将名为“p_客户信息表_姓名”的存储过程 的功能修改为查找客户编号为20130003的客户信息,并将结果传递给一个参数)
use 商品管理数据库
alter proc p_客户信息表_姓名
@name nvarchar(5) output
as
set @name=(select 客户姓名 from 客户信息表 where 客户编号='20130003')

--删除存储过程
注:对于不再使用的存储过程可以将其删除,以节省磁盘空间。删除存储过程不会对它所涉及的数据表等数据库对象产生影响,但调用它的语句再次使用时会产生错误。
drop procedure 存储过程名 --drop 命令表示删除命令,可以删除加码和不加密的存储过程删除时并没有确认是否删除的提示,需谨慎使用。procedure允许只写前四个字母proc。

例:(删除名为“p_进货信息表_商品编号”的已加密的存储过程)
use 商品管理数据库
go
drop proc p_进货信息表_商品编号

--重编译存储过程
注:由于存储过程执行一次后会把编译过程记录到内存中,当再次执行同一个存储过程时则无需编译而直接执行。随着用户对系统的操作,数据库中的数据随时可能发生变化,如果变化涉及了存储过程所关联的数据表,那么存储过程需要重新编译,以得到正确的执行结果。重新编译存储过程有三种方法
1)创建存储过程的同时重新编译
create procedure 存储过程名
with recompile --with recompile命令使存储过程在执行时不保存执行计划,在每次执行时重新编译,以防止覆盖已存在于内存中的执行计划。
as
T-SQL语句

2)执行存储过程的同时重新编译
exec 存储过程名 with recompile --在执行存储过程的同时使用with recompile语句,可以使存储过程在执行时重新编译。

3)使用命令方式预设存储过程重新编译
exec sp_recompile 存储过程名 --可以为已创建的存储过程预设重新编译,即从预设语句执行结束后,下一次执行存储过程时为存储过程重新编译。

例:(使用系统存储过程sp_recompile为存储过程“p_客户信息表_姓名”预设重新编译)
use 商品管理数据库
go
exec sp_recompile 'P_客户信息表_姓名'

 


 注:"--"可看成说明或者注释文本


评论: