在PL/SQL程序開發中,為了方便實現模塊化程序的管理,可以將PL/SQL元素(如存儲過程、函數、變量、常量、自定義數據類型、游標等)根據模塊的程序結構組織在一起,存放在一個包中,稱為一個完整的單元,并在編譯之后存儲在數據庫服務器中,作為一種全局結構,供應用程序調用。
在Oracle數據庫中,包有兩類,一類是系統內置的包,每個包實現特定的應用過程、函數、常量等的集合,如DBMS_OUTPUT.put_line()就是調用了DBMS_OUTPUT包中的put_line()函數;
另一類是根據應用需要由用戶創建的包。
包由包規范(specification)和包體(body)兩部分組成,在數據庫中獨立存儲。包的創建包括包規范和包體的創建。
2.包的創建和應用
- 包的創建
創建包規范的格式如下:
CREATE [OR REPLACE] PACKAGE 包名稱IS|AS
元素名稱定義(類型、變量、存儲過程、函數、游標、異常等)
END [包名稱];
元素聲明的順序可以是任意的,但必須先聲明再使用。過程和函數只聲明,不進行具體的實現。
包體負責包規范中定義的函數或存儲過程的具體代碼實現,如果在包體中定義了包規范中沒有的元素,則此部分元素將被設置為私有訪問,只能由同一包中的函數或存儲過程使用。此外只有在包規范已經創建的條件下,才可以創建包體,如果包規范中不包含任何函數或存儲過程,則可以不創建包體。
創建包體的格式如下:
CREATE [OR REPLACE] PACKAGE BODY 包名稱IS|AS
元素結構實現;
END [包名稱];
在創建包體時需要注意:
包體中的名稱應與包規范中的包名稱保持一致。
包體中存儲過程和函數的聲明格式必須與包規范中的聲明完全一致。
包的調用格式如下:
begin
pkg_demo.proc_insert_users(‘2022-1-5’,‘yyyy-mm-dd’);
pkg_demo.proc_update_users(‘2022-10-5’,‘yyyy-mm-dd’);
end;
【例7-15】創建一個包,該包中包括一個存儲過程PRINT_ENAME,在包體中使用存儲過程實現輸出文字的功能,然后在建立存儲過程調用該包。
具體代碼如下:
—創建包規范
create or replace package EMPLOYEE_PKG
as
procedure PRINT_ENAME;
end EMPLOYEE_PKG;
—創建包體
CREATE OR REPLACE PACKAGE BODY employee_pkg as
Procedure print_ename is
Begin
Dbms_output.put_line(‘我們一定要學習好數據庫’);
End print_ename;
End employee_pkg;
—創建調用該包
CREATE OR REPLACE Procedure callEMPLOYEEPKG
as
begin
EMPLOYEE_PKG.PRINT_ENAME;
End callEMPLOYEEPKG;
執行后,如圖7-23所示。
圖7-23執行計算職工年薪函數
2)包的持續性
在包規范中,所有聲明的元素都具有全局作用域,元素的值在整個用戶會話期間將一直存在,因此在用戶會話期間,元素可以在應用程序各個部分的代碼中被引用。每個用戶會話都會維護屬于自己會話的元素的副本,用戶之間的元素互不干擾。這種在用戶會話期間元素值和狀態的持續性被稱為包的持續性。包的持續性具體可以體現在包中變量的持續性和游標持續性上。
變量的持續性是指,當用戶調用包時,系統會為每個調用者創建屬于該用戶的變量副本,并在用戶的整個會話期間持續存在。包變量對當前會話用戶是私有的。
【例7-16】在test用戶下創建一個包,該包中包括變量 pkgvar,設置該變量初始值為0。建立存儲過程proc_set_var重新給該變量賦值,然后在建立函數fun_get_var 調用包pkgvar。
登錄scott用戶,在該用戶下調用存儲過程proc_set_var給變量賦值為10,查詢變量 pkgvar
的值。登錄sy 用戶,在該用戶下調用存儲過程proc_set_var給變量賦值為20,在scott下查詢變量 pkgvar的值。
本例中兩個不同用戶同時對一個包變量進行存取操作,通過變量值驗證包變量在用戶會話期間的持續性。
創建包含變量的包,存儲過程代碼如下:
create or replace package pkg_varas
pkgvar number:=0;
end pkg_var;
–創建設置變量值的存儲過程
create or replace procedure proc_set_var(p_var number)as
begin
pkg_var.pkgvar:=p_var;
end proc_set_var;
創建獲取包變量值的函數,代碼如下:
create or replace function fun_get_var return number
As
begin
return pkg_var.pkgvar;
end fun_get_var;
登錄scott 用戶,調用存儲過程后,查詢函數中變量的值,代碼如下:
Connect scott/tiger@ ;
EXECUTE proc_set_var(10);
Select fun_ get_var FROM dual ;
執行后,如圖7-24所示。
圖7-24查看變量的值
由上述結果可以看出,此時包變量的值為10。接下來通過用戶 sys啟動另一個 SQL * Plus 窗口,此時訪問testt用戶下包變量的值仍為初始值0,然后重新設置包變量值為20,代碼如下:
登錄到sys用戶,查看變量的值
Connect sys/sjk@orcl;
–給變量賦值為20
EXECUTE proc_set_var(20);
Select fun_get_var from dual;
接下來回到scott用戶下,此時再次查詢包變量的值,會發現包變量仍為10,并沒有受 用戶操作的影響,
3)使用數據字典,查看包
通過查詢數據字典視圖user_objects、user_source查看當前用戶的所有包規范、包體,具體代碼如下:
select object_type,object_name,status from user_objectswhere object_type in (‘PACKAGE’,‘PACKAGE BODY’);
執行后如圖7-25所示。
圖7-25查看包的基本信息
4)重新編譯包
包的重新編譯包括對包規范和包體整體進行重新編譯或者分別進行重新編譯。其語法如下:
alter package 包名稱 compile;
alter package 包名稱 compile specification;
alter package 包名稱 compile body;
COMPILE表示重新編譯包規范和包體。
COMPILE SPECIFICATION 表示重新編譯包規范。
COMPILE BODY表示重新編譯包體。
分別重新編譯包規范和包體
alter package pkg_varas compile specification;
alter package pkg_varas compile body;
5)刪除包
當不需要使用定義的包規范或包時,用戶可以使用刪除整個包,也可以只刪除包體。
刪除包格式如下:
drop package 包的名稱;
刪除包規范的同時會將其對應的包體一起刪除。
6)系統常用包
在Oracle中,除了可以使用用戶創建的包外,還可以利用Oracle系統所提供的開發部進行代碼的編寫,方便應用程序的開發。下述是幾個常用的系統包:
dbms_output包:是最常用的一個系統包 。
dbms_output.put_line()函數就是其中的一個子程序。
dbms_alter包:用于數據庫報警,允許會話間通信。
dbms_job包:用于任務調度服務。
dbms_lob包:用于處理大對象操作。
dbms_pipe包:用于數據庫管道,允許會話間通信。
dbms_sql包:用于執行動態SQL。
utl_file包:用于文件的輸入輸出。
除了utl_file包存儲在服務器和客戶端外,其他的包均存儲在服務器中。