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;