標籤:style blog color io 使用 ar 資料 div cti
一、PL/SQL包概述
1. 什麼是PL/SQL包:
相關組件的組合:PL/SQL類型、變數,資料結構,和運算式、子程式: 過程和函數
2. 包的組成部分:
由兩部分組成:
包頭
包體
3. 包的優點
一次讀取多個對象進入記憶體
二、PL/SQL包的組件
包頭:公用部分:包內和包外的程式都可以訪問
包體:私人部分:包體定義的變數或者程式只能被本包內的程式調用
1. 建立包頭
文法:
CREATE [OR REPLACE] PACKAGE package_name IS|AS public type and variable declarations subprogram specificationsEND [package_name];
OR REPLACE選項刪除並且重新建立包
在包頭聲明的變數初始化值預設為NULL
所有在包頭聲明的結構,對於所有授予該包許可權的使用者都是可見的
包聲明樣本: comm_pkg
CREATE OR REPLACE PACKAGE comm_pkg IS std_comm NUMBER := 0.10; --initialized to 0.10 PROCEDURE reset_comm(new_comm NUMBER);END comm_pkg;/STD_COMM 是一個全域變數,初始為0.10RESET_COMM 用於重新設定獎金的過程,它在包體中被定義
2. 建立包體
文法:
CREATE [OR REPLACE] PACKAGE BODY package_name IS|AS private type and variable declarations subprogram bodies[BEGIN initialization statements]END [package_name];
OR REPLACE選項刪除並且重新重建包體
包體中定義的標識符是私人的,包體之外不可見
所有的私人結構,在引用前必須先聲明
公用結構在包體中是可見的
create or replace package comm_pkg is std_comm number := 0.10; procedure reset_comm(new_comm number);end;create or replace package body comm_pkg is function validate(comm number) return boolean is max_comm employees.commission_pct%type; begin select max(commission_pct) into max_comm from employees; return(comm between 0 and max_comm); end validate; procedure reset_comm(new_comm number) is begin if validate(new_comm) then std_comm := new_comm; else raise_application_error(-20210, ‘Bad Commission‘); end if; end reset_comm;end;
三、調用包中的子程式
在同一個包內調用子程式:
CREATE OR REPLACE PACKAGE BODY comm_pkg IS ... PROCEDURE reset_comm(new_comm NUMBER) IS BEGIN IF validate(new_comm) THEN std_comm := new_comm; ELSE ... END IF; END reset_comm;END comm_pkg;
在sqlplus中調用包中的過程:
SQL> execute comm_pkg.reset_comm(0.15);SQL> set serveroutput on;SQL> eddeclarev_std_comm comm_pkg.std_comm%type;beginv_std_comm := comm_pkg.std_comm;dbms_output.put_line(v_std_comm);end;/結果:SQL> /std_comm:.15PL/SQL procedure successfully completed
在不同模式下調用包內的過程
SQL> conn hr/hrSQL> grant execute on comm_pkg to scott;conn scott/tigerSQL> execute comm_pkg.reset_comm(0.36);PL/SQL procedure successfully completedSQL> SQL> declare 2 v_std_comm comm_pkg.std_comm%type; 3 begin 4 v_std_comm := comm_pkg.std_comm; 5 dbms_output.put_line(‘v_std_comm:‘ || v_std_comm||‘std_comm:‘ || comm_pkg.std_comm); 6 end; 7 /v_std_comm:.36std_comm:.36PL/SQL procedure successfully completed
注意:千萬不要在sql視窗中寫入這段話,不然執行過程是在sql中執行,全域變數存在於sql進程中嗎,不會存在sql視窗中,所以在sql視窗中訪問到的永遠都是std_comm的初始值:0.10
四、建立和使用無體包
create or replace package global_consts is mile_2_kilo CONSTANT NUMBER := 1.6093; kilo_2_mile CONSTANT NUMBER := 0.6214; yard_2_meter CONSTANT NUMBER := 0.9144; meter_2_yard CONSTANT NUMBER := 1.0936;end;
無體包內聲明的變數時全域變數,包外的子程式或者匿名塊都可以使用
在匿名塊中使用:
BEGIN DBMS_OUTPUT.PUT_LINE(‘20 miles = ‘ || 20 * global_consts.mile_2_kilo || ‘ km‘);END;
在子程式中調用:
CREATE FUNCTION mtr2yrd(m NUMBER) RETURN NUMBER ISBEGIN RETURN(m * global_consts.meter_2_yard);END mtr2yrd;beginDBMS_OUTPUT.PUT_LINE(mtr2yrd(1));end;
五、在資料字典中查看包的資訊
查看包頭資訊:
SELECT text FROM user_source WHERE name = ‘COMM_PKG‘ AND type = ‘PACKAGE‘;
查看包體資訊:
SELECT text FROM user_source WHERE name = ‘COMM_PKG‘ AND type = ‘PACKAGE BODY‘;
六、使用包的優勢
1. 模組化: 封裝相關的結構
2. 更加容易維護: 將相關的邏輯功能組合到一起
3. 使應用設計更加容易: 包頭和包體的編譯是分開進行的
4. 隱藏資訊:
對於應用,只有聲明部分是可見的
包體的私人部分被隱藏並且不能被應用訪問
包體中的所有代碼被隱藏
5. 提高了效能:
當包第一次被引用的時候,包內的所有內容全部被載入到記憶體中
對於所有的使用者來講,在記憶體中只複製一次
簡化了依賴性
6. 重載: 多個子程式相同的名
七、刪除包
使用如下文法刪除包頭和包體:
DROP PACKAGE package_name;刪除包體文法:DROP PACKAGE BODY package_name;
oracle包概述(一)【weber出品】