1、為什么要使用包?
答:在一個大型項目中,可能有很多模塊,而每個模塊又有自己的過程、函數等。而這些過程、函數默認是放在一起的(如在PL/SQL中,過程默認都是放在一起的,即Procedures中),這些非常不方便查詢和維護,甚至會發生誤刪除的事件。所以通過使用包就可以分類管理過程和函數。
而且在包中還可以自定義自定義類型,從而在過程和函數中可以直接使用自定義變量。Oracle中包的概念與JAVA中包的概念非常類似,只是JAVA中的包是為了分類管理類,但是關鍵字都是package。
包分兩部分,包規范和包體。
2、包的使用
(1)定義包規范,包規范可單獨存在。
--定義包規范
create or replace package p_stu
as
--定義結構體
type re_stu is record(
rname student.name%type,
rage student.age%type
);
--定義游標
type c_stu is ref cursor;
--定義函數
function numAdd(num1 number,num2 number)return number;
--定義過程
procedure GetStuList(cid in varchar2,c_st out c_stu);
end;
(2)實現包規范,即包體,名稱必須一致,同樣的游標定義不能出現,但結構體可以,方法、過程必須實現。
--實現包體,名稱一致。
create or replace package body p_stu
as
--游標和結構體,包規范中已聲明,包體中不用再聲明,直接使用。
--實現方法
function numAdd(num1 number,num2 number)return number
as
num number;
begin
num:=num1+num2;
return num;
end;
--實現過程
procedure GetStuList(cid varchar2,c_st out c_stu)
as
r_stu re_stu; --直接使用包規范中的結構
begin
open c_st for select name,age from student where classid=cid;
-- 如果已經在過程中遍歷了游標,在使用這個過程的塊中,將沒有值。
-- loop
-- fetch c_st into r_stu;
-- exit when c_st%notfound;
-- dbms_output.put_line('姓名='||r_stu.rname);
-- end loop;
end;
end;
(3)使用
declare
c_stu p_stu.c_stu; --定義包中游標變量
r_stu p_stu.re_stu; --定義包中結構體變量
num number;
begin
--使用及遍歷包中過程返回的結果集
p_stu.GetStuList('C001',c_stu);
loop
fetch c_stu into r_stu;
exit when c_stu%notfound;
dbms_output.put_line('姓名='||r_stu.rname);
end loop;
--使用包中的方法
select p_stu.numAdd(5,6) into num from dual;
dbms_output.put_line('Num='||num);
end;