2.2.4过程、函数与包
过程、函数与包都属于PL/SQL语句块中的命名块,过程和函数统称为子程序。过程和函数非常相似,具有如下特点:
(1)都具有名称,可以接收或者传入参数。
(2)都具有声明部分、执行部分和异常处理部分。
(3)在使用前会被编译并存储到数据库中,可以使用Toad或者Oracle SQL Developerr来查看数据库中已经存在的过程或者函数。
注意:函数和过程最大的不同在于函数具有返回值,而过程没有。
CREATE OR REPLACE PROCEDURE 过程名(参数1 IN 数据类型,参数2 out 数据类型) IS
--定义/初始化变量
变量名1 数据类型;
变量名2 数据类型 := 变量值;
BEGIN
--存储过程主内容
END 过程名;
包是一个逻辑单位,PL/SQL可以让开发人员把逻辑相关的类型、变量、游标和子程序放在一个包内,这样更加清楚,易理解。包通常由如下两部分组成。
包规范部分:包规范部分定义了应用程序的接口,他声明了类型、常量、变量、异常、游标和可以使用的子程序声明。
包体部分:包体用于实现包规范声明部分的子程序和游标。
包规范的建立使用DECLARE、PACKAGE语句、包体的建立使用CREATE PACKAGEBODY语句。比如为更好的创建学生判断成绩绩点这个功能的代码,创建一个名为updateStuMark的包,包中包含了几个存储过程与函数。代码如下所示,
--代码:学生更新绩点管理包代码
--包规范定义
create or replace package updateStuMark is
--获取学生绩点的方法
function getMarkBySore(score in number) return varchar2;
--对学生的绩点进行更新的过程
procedure updateAllStuMark;
end updateStuMark;
create or replace package body updateStuMark is
--包体定义
function getMarkBySore(score in number) return varchar2 is
return varchar2(10);
v_mark varchar2(10);
begin
if score>90 then
v_mark := 'A';
elsif score>80 then
v_mark := 'B';
elsif score>70 then
v_mark := 'C';
elsif score>=60 then
v_mark := 'D';
else
v_mark := 'F';
end if;
return v_mark;
end ;
procedure updateAllStuMark
as
--姓名
v_name varchar2(20);
--科目
v_subject varchar2(20);
--成绩
v_score number;
--绩点
v_mark varchar2(20);
cursor c_emp is
select name,subject,score from student_score;
begin
--打开游标
open c_emp;
Loop
--提取游标
fetch c_emp
into v_name,v_subject,v_score;
--如果没有数据则退出游标
exit when c_emp%notfound;
--调用函数获取绩点
v_mark := getMarkBySore(v_score);
--更新绩点
update student_score set mark = v_mark
where name = v_name and subject = v_subject;
dbms_output.put_line(v_name||'成绩:'||v_subject||':'||v_score||'分,绩点:'||v_mark);
end loop;
--关闭游标
close c_emp;
exception
when others then
dbms_output.put_line('没有找到学生数据');
end;
end updateStuMark;
begin
updateStuMark.updateAllStuMark();
end;
从代码中可以看到,在包规范中,只是对子程序进行了声明,并没有包含实现代码。包规范中除了包含子程序外,还可以包含变量、常量及游标的定义,在包体中包含了过程和函数的实际的代码,编译并执行包创建动作后,包被保存到了Oracle数据字典中.