个人主页:这个昵称我想了20分钟
✨往期专栏:【速成之路】jQuery
️专栏:【速成之路】SQL server
往期回顾:
【SQL server速成之路】数据库基础
【SQL server速成之路】数据库和表(一)
【SQL server速成之路】数据库和表(二)
【SQL server速成之路】数据库的查询
【SQL server速成之路】数据库的视图和游标
【SQL server速成之路】T-SQL语言(一)
【SQL server速成之路】T-SQL语言(二)
【SQL server速成之路】函数
【SQL server速成之路】索引与数据完整性
【SQL server速成之路】触发器
使用存储过程有以下优点:
(1)存储过程在服务器端运行,执行速度快。
(2)存储过程执行一次后,其执行规划就驻留在高速缓冲存储器,在以后的操作中,只需从高速缓冲存储器中调用已编译好的二进制代码执行,提高了系统性能。
(3)确保数据库的安全。
(4)自动完成需要预先执行的任务。
(1)系统存储过程
系统存储过程是由系统提供的存储过程,可以作为命令执行各种操作。系统存储过程定义在系统数据库master中,其前缀是sp_,它们为检索系统表的信息提供了方便快捷的方法。
(2)用户存储过程
用户存储过程是指在用户数据库中创建的存储过程,这种存储过程可以接受和返回用户提供的参数,完成用户指定的数据库操作,其名称不能以sp_为前缀。SQL Server 中,用户存储过程可以使用T-SQL语言编写,也可以使用CLR方式编写。
在用户存储过程的定义中不能使用下列对象创建语句:
SET PARSEONLY、SET SHOWPLAN_TEXT、SET SHOWPLAN_XML、SET SHOWPLAN_ALL、CREATE SCHEMA、CREATE FUNCTION、ALTER FUNCTION、CREATE PROCEDURE、ALTER PROCEDURE、CREATE TRIGGER、ALTER TRIGGER、CREATE VIEW、ALTER VIEW、USE database_name等。
1.通过T-SQL命令创建存储过程
如果要通过SQL命令定义一个存储过程查询xsbook数据库中每位读者当前的借书情况,然后调用该存储过程,实现步骤如下 :
① 定义如下存储过程
USE xsbook
GO
CREATE PROCEDURE readers_info
AS
SELECT DISTINCT xs.借书证号,姓名,book.ISBN,书名,索书号
FROM xs, jy, book
WHERE xs.借书证号=jy.借书证号 AND book.ISBN=jy.ISBN
GO
② 调用存储过程
EXEC readers_info
创建存储过程的语句是CREATE PROCEDURE或CREATE PROC,两者同义。
语法格式:
CREATE { PROC | PROCEDURE } [<数据库架构名>.] <存储过程名> /*定义过程名*/
[ { @parameter [ type_schema_name. ] data_type } /*定义参数的类型*/
[ VARYING ] [ = default ] [ OUT | OUTPUT ] [READONLY] ][ ,...n ] /*定义参数的属性*/
[ WITH {[ RECOMPILE ] [,] [ ENCRYPTION ] }] /*定义存储过程的处理方式*/
AS <sql_statement> [;] /*执行的操作*/
说明:
(1)存储过程名:必须符合标识符规则,且对于数据库及其所有者必须惟一;创建局部临时过程,可以在存储过程名前面加一个“#”;创建全局临时过程,可以在存储过程名前加“##”。
(2)@parameter:为存储过程的形参,形参局部于该存储过程,参数名必须符合标识符规则,并且首字符必须为@,可定义一个或多个形参,执行存储过程时应提供相应的实在参数,除非定义了该参数的默认值。
(3)data_type:用于指定形参数据类型,形参类型可为SQL Server支持的任何类型,但cursor 类型只能用于 OUTPUT 参数,如果指定形参类型为 cursor,必须同时指定 VARYING 和OUTPUT 关键字,OUT与OUTPUT关键字意义相同。
(4)VARYING:指定作为输出参数支持的结果集。该参数由存储过程动态构造,其内容可能发生改变,仅适用于cursor参数。
(5)default:指定存储过程输入参数的默认值,默认值必须是常量或NULL。如果存储过程使用了带LIKE关键字的参数,默认值中可以包含通配符(%、_、[]和[^]),如果定义了默认值,执行存储过程时根据情况可不提供实参。
(6)READONLY:指定不能在存储过程的主体中更新或修改参数。如果参数类型为用户定义的表类型,则必须指定READONLY。
(7)RECOMPILE:表明SQL Server每次运行该过程时,将对其重新编译;ENCRYPTION表示SQL Server 加密syscomments表中包含CREATE PROCEDURE 语句文本的条目。
(8)参数sql_statements:代表过程体包含的T-SQL语句,存储过程体中可以包含一条或多条T-SQL语句,除了DCL、DML与DDL命令外,还能包含过程式语句,如变量的定义与赋值、流程控制语句等。
2.执行存储过程
通过EXECUTE或EXEC命令可以执行一个已定义的存储过程,EXEC是EXECUTE的简写。语法格式:
[ { EXEC | EXECUTE } ]
{ [ @return_status = ]
{ module_name | @module_name_var }
[ [ @parameter = ] { value | @variable [ OUTPUT ] | [ DEFAULT ] }]
[ ,...n ]
}
[;]
说明:
(1)参数@return_status为可选的整型变量,保存存储过程的返回状态,EXECUTE语句使用该变量前,必须对其定义。
(2)参数module_name是要调用的存储过程或用户定义标量函数的完全限定或者不完全限定名称。@module_name_var表示局部定义的变量名,保存存储过程或用户定义函数的名称。
(3)@parameter表示CREATE PROCEDURE或CREATE FUNCTION语句中定义的参数名,value为实参。如果省略@parameter,则后面的实参顺序要与定义时参数的顺序一致。
3.举例
(1)设计简单的存储过程
【例1】 利用xsbook数据库中的xs、book和jyls表,编写一个无参存储过程用于查询每个读者的借阅历史,然后调用该存储过程。
CREATE PROCEDURE history_info
AS
SELECT a.借书证号,姓名, b.ISBN,书名,索书号, 借书时间,还书时间
FROM xs a INNER JOIN jyls b
ON a.借书证号 = b.借书证号 INNER JOIN book c
ON b.ISBN= c.ISBN
history_info存储过程可以通过以下方法执行:
EXECUTE history_info
或
EXEC history_info
如果该过程是批处理中的第一条语句,则可使用:
history_info
(2)使用带参数的存储过程
【例2】 创建存储过程,根据xsbook数据库的3个表查询指定读者当前的借书情况。
CREATE PROCEDURE reader_info @lib_num char (8)
AS
SELECT a.借书证号,姓名,b.ISBN, 书名, 索书号
FROM xs a, jy b, book c
WHERE a.借书证号 = b.借书证号 AND b.ISBN=c.ISBN AND a.借书证号=@lib_num
reader_info存储过程有多种执行方式,如下所示:
EXECUTE reader_info '131101'
执行结果如图所示。
以下命令的执行结果与上面相同:
EXECUTE reader_info @lib_num='131101'
(3)使用带有通配符参数的存储过程
【例3】 利用xsbook数据库中xs、book、jyls表创建一存储过程book_inf,查询指定图书的借阅历史。该存储过程在参数中使用了模糊查询,如果没有提供参数,则使用预设的默认值。
CREATE PROCEDURE book_inf @bname varchar(30) = '%计算机%'
AS
SELECT b.ISBN,书名,姓名,借书时间,还书时间
FROM xs a ,jyls b,book c
WHERE a.借书证号 =b.借书证号 AND b.ISBN= c.ISBN
AND 书名 LIKE @bname
执行存储过程:
EXECUTE book_inf /*参数使用默认值*/
或者:
EXECUTE book_inf 'WEB%' /*传递给@bname的实参为'WEB%'*/
(4)使用带OUTPUT参数的存储过程
【例4】 编写存储过程,统计指定图书在给定时间段内的借阅次数,存储过程中使用了输入和输出参数。
CREATE PROCEDURE bstatistics @bname varchar(26),@startdate date,
@enddate date,@total int OUTPUT
AS
SELECT @total=count(索书号)
FROM jy a,book b
WHERE 书名 like @bname AND a.ISBN= b.ISBN AND
借书时间>=@startdate AND 借书时间<=@enddate
在调用存储过程bstatistics时,存储过程定义时的形参名和调用时的变量名不一定要匹配,不过数据类型和参数位置必须匹配。例如执行语句如下:
DECLARE @book_name char(30),@total int
SET @book_name='Java编程思想'
EXECUTE bstatistics @book_name, '2014-01-01','2014-10-08',@total OUTPUT
SELECT @book_name, @total
(5)使用OUTPUT游标参数的存储过程
OUTPUT 游标参数用于返回存储过程的局部游标。
【例5】 在 xsbook数据库的xs表上声明并打开一个游标。
CREATE PROCEDURE reader_cursor @reader_cur CURSOR VARYING OUTPUT
AS
SET @reader_cur = CURSOR FORWARD_ONLY STATIC FOR
SELECT 借书证号,姓名,专业,性别,出生时间,借书量
FROM xs
OPEN @reader_cur
在如下的批处理中,声明一个局部游标变量,执行上述存储过程并将游标赋值给局部游标变量,然后通过该游标变量读取记录。
DECLARE @MyCursor CURSOR
EXEC reader_cursor @reader_cur = @MyCursor OUTPUT
FETCH NEXT FROM @MyCursor
WHILE (@@FETCH_STATUS = 0)
FETCH NEXT FROM @MyCursor
CLOSE @MyCursor
DEALLOCATE @MyCursor
(6)使用 WITH ENCRYPTION 选项
WITH ENCRYPTION 子句对用户隐藏存储过程的文本。
【例6】 创建加密过程,使用 sp_helptext 系统存储过程获取关于加密过程的信息,然后尝试直接从syscomments表中获取关于该过程的信息。
CREATE PROCEDURE encrypt_this WITH ENCRYPTION
AS
SELECT *
FROM xs
通过系统存储过程sp_helptext可显示规则、默认值、未加密的存储过程、用户定义函数、触发器或视图的文本。
执行如下语句:
EXEC sp_helptext encrypt_this
结果集为提示信息:“对象’encrypt_this’的文本已加密”。
(7)创建用户定义的系统存储过程
【例7】 创建存储过程sp_showtable,显示以xs开头的所有表名及其对应的索引名。如果没有指定参数,该存储过程将返回以book开头的所有表名及对应的索引名。
CREATE PROCEDURE sp_showtable @TABLE varchar(30) = 'book%'
AS
SELECT tab.name AS TABLE_NAME,
inx.name AS INDEX_NAME,
indid AS INDEX_ID
FROM sysindexes inx INNER JOIN sysobjects tab ON tab.id = inx.id
WHERE tab.name LIKE @TABLE AND indid <>0 AND indid <>255
如下语句调用存储过程sp_showtable:
EXEC sp_showtable 'xs%'
使用ALTER PROCEDURE命令可修改已存在的存储过程。
语法格式:
ALTER { PROC | PROCEDURE } [<数据库架构名>.] <存储过程名>
[ { @parameter data_type }
[ VARYING ] [ = default ] [ OUT[PUT] ]
][ ,...n ]
[ WITH {[ RECOMPILE ] [,] [ ENCRYPTION ] }]
AS <sql_statement>
[;]
【例8】 对存储过程readers_info进行修改。
ALTER PROCEDURE readers_info
AS
SELECT DISTINCT xs.借书证号,姓名,book.ISBN,书名,索书号
FROM xs,jy,book
WHERE xs.借书证号=jy.借书证号 AND book.ISBN=jy.ISBN AND 专业= '计算机'
如果确认一个数据库的某个存储过程与其它对象没有任何依赖关系,则可用DROP PROCEDURE语句永久地删除该存储过程。
语法格式:
DROP PROCEDURE { <存储过程名>} [ ,…n ]
若要查看过程名列表,可使用sp_help系统存储过程。
【例9】 删除 xsbook数据库中的readers_info 存储过程。
IF EXISTS(SELECT name FROM sysobjects WHERE name='readers_info ')
DROP PROCEDURE readers_info
(1)创建存储过程。例如,如果要通过图形向导方式定义一个存储过程来查询xsbook数据库中每个学生的借书信息,可以列出其主要步骤如下:
在“对象资源管理器”中展开“数据库”→ “xsbook”→选择其中的“可编程性”→右击“存储过程”→在弹出的快捷菜单中选择“新建存储过程”菜单项,打开“存储过程脚本编辑”窗口。在该窗口中输入要创建的存储过程的代码,输入完成后单击“执行”按钮,若执行成功则创建完成。
(2)执行存储过程。在“xsbook”数据库的“存储过程”目录下选择要执行的存储过程,右击鼠标,选择“执行存储过程”菜单项。在弹出的“执行过程”窗口中会列出存储过程的参数形式,如果“输出参数”栏为否则表示该参数为输入参数,用户需要设置输入参数的值,在“值”一栏中输入即可。
(3)修改存储过程。在“存储过程”目录下选择要修改的存储过程,右击鼠标,在弹出的快捷菜单中选择“修改”菜单项,打开“存储过程脚本编辑”窗口,在该窗口中修改相关的T-SQL语句。修改完成后,执行修改后的脚本,若执行成功则修改了存储过程。
(4)删除存储过程。选择要删除的存储过程,右击鼠标,在弹出的快捷菜单中选择“删除”菜单项,根据提示删除该存储过程。