配色: 字号:
《SQL Server 2005基础教程及上机指导》第6章 存储过程
2023-05-25 | 阅:  转:  |  分享 
  
第6章 存 储 过 程6.1 存储过程简介6.2 使用存储过程6.3 可编程化存储过程6.4 上机实验习题   存储过程是一个T-
SQL语句的预编译集合,它创建于数据库服务器并且以一个名称存储为一个单元,可以被应用程序调用,也可以被另一个存储过程或触发器调用。
        本章学习目标:   (1) 掌握创建、修改和删除存储过程的方法。   (2) 理解存储过程的输入参数、输出参数、
默认参数、返回值等重要概念,并掌握它们的运用技巧。   (3) 能够灵活运用存储过程来解决实际问题。     存储过程具有以下
优点:   (1) 存储过程允许模块化编程。存储过程在被创建以后可以在程序中被多次调用,而不必重新编写该存储过程的SQL语句。  
 (2) 存储过程能够实现较快的执行速度。如果某一操作包含大量的T-SQL代码或分别被多次执行,那么存储过程要比批处理的执行速度快
很多。6.1 存储过程简介  (3) 存储过程能够减少网络流量。对于同一个针对数据库对象的操作(如查询、修改),如果这一操作所涉
及到的T-SQL语句被组织成一存储过程,那么当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,否则将是多条SQL 语句
,从而大大增加了网络流量,降低网络负载。   (4) 存储过程可被作为一种安全机制来充分利用。系统管理员通过对执行某一存储过程的权
限进行限制,从而能够实现对相应的数据访问权限的限制,避免非授权用户对数据的访问,保证数据的安全。   6.2.1 创建存储过
程   创建存储过程的语法如下:   CREATE PROC [ EDURE ] procedure_name       [
{ @parameter data_type }         [ OUTPUT ]       ] [,...n ]    
     AS sql_statement [ ...n ]6.2 使用存储过程  参数的含义如下:   procedure_n
ame:新存储过程的名称。过程名称必须遵循有关标识符的规则,并且在架构中必须唯一。   @ parameter:过程中的参数。在C
REATE PROCEDURE语句中可以声明一个或多个参数。   通过使用at符号(@)作为第一个字符来指定参数名称。参数名称必须
符合有关标识符的规则。   data_type:参数以及所属架构的数据类型。  OUTPUT:指示参数是输出参数。此选项的值可以返
回给调用EXECUTE的语句。使用 OUTPUT 参数将值返回给过程的调用方。   :要包含在过程中
的一个或多个T-SQL语句。   下面将演示怎样创建一个存储过程,假设想要列出2002级8班(也就是学号以“200208”开头)学
生的学号、姓名和性别,只需要一条SELECT语句就可以完成,输入代码清单6-1所示的代码并执行。   当上面的代码被执行完
毕后,可以看到已经存在名称为“spStudents028”的存储过程,如图6-1所示。  图6-1 被创建的spStudents
028存储过程6.2.2 运行存储过程   执行存储过程的语法也很简单,只需要在EXECUTE语句(或简写为EXEC)后面加上存
储过程名称就可以了,比如要执行上面刚创建的存储过程,输入代码清单6-2所示的代码并执行,执行结果如图6-2所示。     图6-2
存储过程执行结果6.2.3 修改存储过程   存储过程被创建之后,有时候由于种种原因还要对它进行修改,修改存储过程可以使用A
LTER PROCEDURE语句,语法结构如下:    ALTER PROC [ EDURE ] procedure_name
      [ { @parameter data_type }          [ OUTPUT ]       ] AS s
ql_statement [ ...n ]  其实这个语法与创建存储过程的语法很类似,只是把CREATE改成了ALTER,其余部分
的含义在上一节中已经介绍,这里不再重复。现在我们把上一个例子作一点改动,即列出2002级8班(也就是学号以“200208”开头)女
同学的学号、姓名和性别,输入代码清单6-3所示的代码并执行,执行结果如图6-3所示,从结果图可以看出,对存储过程的修改已经起作用了
。  图6-3 存储过程执行结果6.2.4 删除存储过程   当不需要某个存储过程时,就可以将它从数据库中删除,删除存储过程的
语句为DROP PROCEDURE,具体语法结构如下:   DROP PROCEDURE <存储过程名称>  注意,对存储过程的
删除操作是永久且无法恢复的,所以在删除之前一定要谨慎。比如要把前面例子所创建的存储过程spStudents028删除,然后试图再次
运行它,但是系统给出了找不到存储过程的信息,输入代码清单6-4所示的代码并执行,结果如图6-4所示。  图6-4 找不到存储过程
spStudents028     在存储过程中编写的代码可以是很复杂的,功能也可以是很强大的。6.3 可编程化存储过程6
.3.1 设置参数   在声明参数时需要注意,必须使用@符号作为第一个字符来指定参数名称,参数名称必须符合标识符的规则,在一个存
储过程中可以定义一个或多个参数,每个参数仅用于该存储过程的局部变量。  下面举例说明带参数存储过程的创建,即创建一个能根据所指定的
科目名称来查询考生信息的存储过程,输入代码清单6-5所示的代码并执行,即可创建并运行该存储过程。     在代码中,我们指定了一个
名为@subjectName的参数,它的参数类型为char(50)(必须注意数据类型应该和表中相应的字段的数据类型一致),这个参数
被用在WHERE从句中,用来筛选出相应的考试科目的记录。而在执行语句中,只需在存储过程名称后面直接输入参数值“全国计算机等级考试”
就可以把它传送给参数了,执行结果如图6-5所示。  图6-5 执行带单个参数的存储过程spGetInfoBySubjectNam
e  接下来查询另一科目“局域网管理员考试”的信息,输入代码清单6-6所示的代码并执行,结果如图6-6所示。     图6-6
执行带单个参数的存储过程spGetInfoBySubjectName  存储过程是可以指定多个参数的,比如想查询指定的科目名称和指
定级别的考试信息,这里就要用到两个参数:一个是@subjectName,用来存放科目信息;另一个是@degree,用来存放级别信息
。输入代码清单6-7所示的代码并执行,在代码中先创建存储过程,然后执行两次,但每次执行所输入的参数值是不同的,所返回的两个结果集如
图6-7所示。  图6-7 执行带两个参数的存储过程spGetInfoBySubjectNameAndDegree  这里需要强
调的是两个参数值的参数问题,在调用存储过程的语句中指定参数的时候,可以只指定参数值而不用指出参数名,但这时各参数值的顺序必须和存储
过程定义中各相应参数的顺序保持一致,否则会导致逻辑上的不正确。但也可以指出参数名与值(即显式写出“@参数名称=参数值”的格式),这
时候参数的顺序可以是任意的,例如下面的例子,对同一个存储过程分别以不同方式调用了两次,两次调用中各参数值的顺序和存储过程定义中各相
应参数的顺序都不一致,但第一次没有指出参数名,所以没有检索到数据,而第二次明确指出参数名,所以得到预期的结果,输入代码清单6-8所
示的代码并执行,所返回的两个结果集如图6-8所示。  图6-8 两次执行存储过程的比较6.3.2 设置默认参数   如果在调用
一个带有参数的存储过程时没有指定参数值,通常存储过程是不能执行的,比如调用上面创建的存储过程spGetInfoBySubjectN
ameAndDegree却没有指定参数,就会返回错误信息。输入代码清单6-9所示的代码并执行,返回的错误信息如图6-9所示。   
  图6-9 没有指定参数值出错  还有另外一种情况也会出错,就是所指定的参数个数与存储过程所声明的参数个数不同,例如存储过程s
pGetInfoBy SubjectNameAndDegree有两个参数,下面的例子在调用它时却只输入了一个参数,结果是系统也返回
错误信息,但这次的错误信息指出的是缺少第二个参数@degree。输入代码清单6-10所示的代码并执行,返回的错误信息如图6-10所
示。     图6-10 没有指定足够个数的参数值时出错  其实,在声明存储过程的参数时是可以为其指定默认值的,如果在调用存储过
程时没有指定参数值,那么认为参数的值是默认值,否则就是所指定的值。对于有多个参数的情况,也可以指定部分参数值,其余的参数则采用默认
值。   为参数指定默认值的语法是在所声明的参数名称后面加上“=<参数值>”。例如,对存储过程spGetInfoBySubject
Name AndDegree进行少许修改,为两个参数@subjectName和@degree分别指定默认值为“全国英语等级考试”和
“一级”,输入代码清单6-11所示的代码并执行。  接下来进行三种方式的调用:第一种方式是两个参数都不指定参数值(即全部采用默认值
);第二种方式是@subjectName采用默认值,而指定@degree的值;第三种方式是两个参数都采用指定的值,具体代码如代码清
单6-12所示,结果如图6-11所示。    图6-11 几种调用方式的比较6.3.3 设置输出参数   在前面的两小节中介绍
了存储过程的参数,但都是输入参数,如果有必要,也可以声明输出参数,声明输出参数的语法为在参数后面加一个OUTPUT关键字。例如继续
对上面所创建的存储过程spGetInfoBySubjectNameAndDegree进一步进行修改,添加一个返回参加指定科目和级别
的所有考生的平均成绩的输出参数@averageScore,输入代码清单6-13所示的代码并执行。  注意,在上面的代码中“@ave
rageScore = AVG(Score)”是指把函数AVG(Score)的结果赋给变量@averageScore,这时候SEL
ECT所返回的就只是一个单个的数值。   接下来将调用修改过后的存储过程,首先声明一个数据类型为FLOAT的临时变量@AvgScr
e,用来存放输出参数的值,在调用时,对于@AvgScre参数也必须在后面加上OUTPUT关键字,我们将使用不同的参数调用两次,以便
对结果进行比较,每次调用后都用SELECT语句来显示输出结果,具体代码如代码清单6-14所示,输出参数的结果如图6-12所示。  
图6-12 显示输出参数的结果6.3.4 存储过程的返回值   实际上存储过程是可以有返回值的,尽管在前面的例子中创建存储过程
时没有显式的返回值语句,而在执行存储过程的时候也没有刻意去获取它的返回值,在这种情况下,如果存储过程能成功执行,则默认自动返回一个
整数0,通过检测这个返回值来确定存储过程的执行状态。若有必要,也可以指定返回值,以反映标识值或影响的行数等信息。   若要获取存储
过程的返回值,可以使用以下语法:   EXEC <变量>=<存储过程名>   下面进行一个获取存储过程返回值的测试,以上一小节所创
建的存储过程为例,具体代码如代码清单6-15所示,执行结果如图6-13所示。  图6-13 显示存储过程的返回值  上面的代码与
之前调用存储过程的方式有少许不同,就是专门声明了一个变量@ReturnValue用来存放返回值,由图可知,存储过程返回了整数值0。
  如本小节开始所述,是可以自定义存储过程的返回值的,只需要在存储过程中使用RETURN 语句,具体语法为   RETURN [
<返回的整数值>]   这里要注意,返回值必须是整数值,当执行到RETURN 语句时,存储过程就会无条件退出,而不管后面是否还有语
句。   这里创建一个按照学号来查找考生的存储过程,如果找不到,则返回-200,表示没有匹配的记录;如果找到,则显示相应的记录,这
时系统就会默认返回0,具体代码如代码清单6-16所示。  上述代码中,EXISTS子句的作用是用来检测是否存在相应的记录,但这里在
它的前面还加了一个NOT,意思就变为如果下面的语句:   SELECT FROM TestInformation WHERE
StudentID =@studentID   没有匹配的记录,就执行RETURN -200,然后退出存储过程,否则就显示结果集
。   现在对这个存储过程进行调用测试,具体代码如代码清单6-17所示,结果如图6-14所示。    图6-14 显示存储过程的
返回值  在代码中,先声明一个变量用来存放返回值,然后进行了两次调用,第一次为查找学号为“20020504”的考生,但是没有找到匹
配的记录,所以返回值为-200(见图6-14上面方框部分);而第二次为查找学号为“20020745”的考生,找到了两条记录,所以先
显示出结果集,然后显示出返回值为0(见图6-14下面方框部分)。     在本章的实验中,利用第3章实验中所创建的两张表Tea
chers2008和Course2008,由于它们的数据在第3章实验中已经被改变,因此在本章实验前需要重新创建它们。重新创建这两张
表的代码参见第3章的代码清单3-52,可按以下步骤运行这段代码:6.4 上 机 实 验  进入“Microsoft SQL Se
rver Management Studio”界面,选择“文件”|“打开”|“文件…”,在弹出的“打开文件”对话框中定位到随本书配
套资源中的代码文件“3-52.sql”,然后单击“连接”,就会在所打开的代码窗口中显示出代码清单3-52的代码,单击工具栏中的
,这样Teachers2008和Course2008就会被重新创建并恢复最原始的数据了。  1.实验一:创建和使用简单存储过程
  1) 实验要求   (1) 熟练运用CREATE PROCEDURE创建存储过程。   (2) 对创建、运行、修改和删除存储过
程有初步的认识。   2) 实验目的   掌握存储过程的基本操作。   3) 实验步骤   进入“Microsoft SQL Se
rver Management Studio”界面,在对象资源管理器中展开节点“WestSVR”|“数据库”,单击选中数据库节点“
WxdStudent”,再单击工具栏按钮“   ”,在所打开的查询窗口中完成以下任务:  (1) 创建一个不带任何参数的存储过程
,名称为ShowAllTeachers,可以输出所有教师的全部数据。   在代码窗口中输入代码清单6-18所示的代码并运行,消息窗
口显示出“命令已成功完成”,则说明存储过程已经被成功创建了。如果展开“WxdStudent”|“可编程性”|“存储过程”节点,可以
看到存储过程ShowAllTeachers,如图6-15所示。  图6-15 存储过程ShowAllTeachers  (2)
运行存储过程ShowAllTeachers,观察结果。   在代码窗口中输入代码清单6-19所示的代码并运行,运行结果如图6-16
所示。     图6-16 运行结果  (3) 修改存储过程ShowAllTeachers,改为只显示姓名(Name)和职称(A
cademicTitle)两列数据,然后运行修改过后的存储过程。   在代码窗口中输入代码清单6-20所示的代码并运行,运行结果如
图6-17所示。     图6-17 运行结果  (4) 删除存储过程ShowAllTeachers,然后尝试运行存储过程,观察
错误信息。   在代码窗口中输入代码清单6-21所示的代码并运行,弹出图6-18所示的错误消息,说明存储过程ShowAllTeac
hers已经从数据库中删除了。     图6-18 错误消息提示  2.实验二:创建和使用带参数的存储过程   1) 实验要求
  (1) 熟悉创建带参数的存储过程的语法。   (2) 理解默认参数的功能。   2) 实验目的   掌握带参数的存储过程的运用
。  3) 实验步骤   进入“Microsoft SQL Server Management Studio”界面,在对象资源管理
器中展开节点“WestSVR”|“数据库”,单击选中数据库节点“WxdStudent”,再单击工具栏按钮“   ”,在所打开的查
询窗口中完成以下任务:   (1) 创建一个带1个参数的存储过程FindTeacherBySex,在参数中指定性别(1表示男,0表
示女),存储过程可以列出相应的老师,并且运行存储过程进行测试。   在代码窗口中输入代码清单6-22所示的代码并运行,运行结果如图
6-19所示。     图6-19 运行结果  (2) 创建一个带一个参数的存储过程FindCourseByLesson Pla
ce,在参数中指定上课地点,存储过程可以列出相应的课程。若不指定参数,则默认为列出在“课室”上课的课程,并且运行存储过程进行测试。
  在代码窗口中输入代码清单6-23所示的代码并运行,运行结果如图6-20所示。   图6-20 运行结果  (3) 创建一个
带两个参数的存储过程ModifyCourseByTeacher,在参数中指定课程名称和教师姓名,存储过程可以将相应课程的授课教师更
改为参数中指定姓名的教师,并且运行存储过程进行测试。   在代码窗口中输入代码清单6-24所示的代码并运行,运行结果如图6-21所
示。  图6-21 运行结果     一、判断题(正确的,在题后括号内画“√”;错误的,在题后括号内画“×”)   1.
如果要执行大量的T-SQL 代码,最好使用存储过程,而不要将代码存放在客户端。    ( )   2.若某个存
储过程定义有输入参数,则调用它时一定要指明参数的值,否则会出错。    ( ) 习 题  3.若某个存储
过程定义有几个参数,则在调用时如果显式指明参数的名称和参数值,则参数的排列顺序可以和参数在存储过程内的声明顺序不一致。 ( )   4.若没有在存储过程内使用RETURN语句,则存储过程就没有返回值。 ( )   5.若执行存储过程失败,则返回0。 ( )  二、填空题   1.创建存储过程的语句为____________,修改存储过程的语句为_______________,删除存储过程的语句为__________________。   2.在创建或修改存储过程的时候可以声明参数,参数分为_________和_________两种类型。   3.若在执行存储过程的同时要获取返回值,则调用的语法为____________________。  三、简答题   1.为什么不把T-SQL程序存放在客户端,而是尽量使用存放在服务器的存储过程?   2.执行存储过程时,若省略EXECUTE关键字,会有什么结果?   3.简述存储过程的输入参数和输出参数的作用,以及默认参数的机制。   4.简述如何设置存储过程的返回值。
献花(0)
+1
(本文系大高老师首藏)