程式包的建立與應用(聰明在于學習,天才在于積累!)
——通過知識共享樹立個人品牌。
繼上七篇:
<a href="http://www.cnblogs.com/huyong/archive/2011/05/13/2045407.html">[推薦]ORACLE PL/SQL程式設計詳解之三:PL/SQL流程控制語句(不給規則,不成方圓)</a>
<a href="http://www.cnblogs.com/huyong/archive/2011/04/27/2030466.html">ORACLE PL/SQL程式設計之八:把觸發器說透</a>
在這篇中,我講給大家講解PL/SQL最引人注目的特色“ORACLE的程式包”,此篇文章花了我近兩周的時間,今天終于出文了。有的地方可能還不全面,望大蝦們多多指教!
一定要推薦、推薦、推薦、推薦、推薦、推薦、推薦、推薦、推薦、推薦、評論與支援呀~!
本篇主要内容如下:
<a href="#_Toc31360">第七章 程式包的建立和應用</a>
<a href="#_Toc14050">7.1 程式包簡介</a>
<a href="#_Toc27869">7.2 程式包的定義</a>
<a href="#_Toc23865">7.3 包的開發步驟</a>
<a href="#_Toc6703">7.4 包定義的說明</a>
<a href="#_Toc10844">7.5 子程式重載</a>
<a href="#_Toc4372">7.6 加密實用程式</a>
<a href="#_Toc4576">7.7 删除包</a>
<a href="#_Toc16531">7.8 包的管理</a>
程式包(PACKAGE,簡稱包)是一組相關過程、函數、變量、常量和遊标等PL/SQL程式設計元素的組合,作為一個完整的單元存儲在資料庫中,用名稱來辨別包。它具有面向對象程式設計語言的特點,是對這些PL/SQL 程式設計元素的封裝。包類似于c#和JAVA語言中的類,其中變量相當于類中的成員變量,過程和函數相當于類方法。把相關的子產品歸類成為包,可使開發人員利用面向對象的方法進行存儲過程的開發,進而提高系統性能。
與進階語言中的類相同,包中的程式元素也分為公用元素和私用元素兩種,這兩種元素的差別是他們允許通路的程式範圍不同,即它們的作用域不同。公用元素不僅可以被包中的函數、過程所調用,也可以被包外的PL/SQL程式通路,而私有元素隻能被包内的函數和過程式所通路。
當然,對于不包含在程式包中的過程、函數是獨立存在的。一般是先編寫獨立的過程與函數,待其較為完善或經過充分驗證無誤後,再按邏輯相關性組織為程式包。
程式包的優點
u 簡化應用程式設計:程式包的說明部分和包體部分可以分别建立各編譯。主要展現 在以下三個方面:
1) 可以在設計一個應用程式時,隻建立各編譯程式包的說明部分,然後再編寫引用該 程式包的PL/SQL塊。
2) 當完成整個應用程式的整體架構後,再回頭來定義包體部分。隻要不改變包的說明部分,就可以單獨調試、增加或替換包體的内容,這不會影響其他的應用程式。
3) 更新包的說明後必須重新編譯引用包的應用程式,但更新包體,則不需重新編譯引用包的應用程式,以快速進行進行應用程式的原形開發。
u 子產品化:可将邏輯相關的PL/SQL塊或元素等組織在一起,用名稱來唯一辨別程式 包。把一個大的功能子產品劃分人适當個數小的功能子產品,分别完成各自的功能。這樣組織的程式包都易于編寫,易于了解更易于管理。
u 資訊隐藏:因為包中的元素可以分為公有元素和私有元素。公有元素可被程式包内的過程、函數等的通路,還可以被包外的PL/SQL通路。但對于私有元素隻能被包内的過程、函數等通路。對于使用者,隻需知道包的說明,不用了解包休的具體細節。
u 效率高:程式包在應用程式第一次調用程式包中的某個元素時,ORACLE将把整個程式包加載到記憶體中,當第二次通路程式包中的元素時,ORACLE将直接從内在中讀取,而不需要進行磁盤I/O操作而影響速度,同時位于内在中的程式包可被同一會話期間的其它應用程式共享。是以,程式包增加了重用性并改善了多使用者、多應用程式環境的效率。
對程式包的優點可總結如下:在PL/SQL程式設計中,使用包不僅可以使程式設計子產品化,對外隐藏包内所使用的資訊(通過使用私用變量),而寫可以提高程式的執行效率。因為,當程式首次調用包内函數或過程時,ORACLE将整個包調入記憶體,當再次通路包内元素時,ORACLE直接從記憶體中讀取,而不需要進行磁盤I/O操作,進而使程式執行效率得到提高。
一個包由兩個分開的部分組成:
包說明(PACKAGE):包說明部分聲明包内資料類型、變量、常量、遊标、子程式和異常錯誤處理等元素,這些元素為包的公有元素。
包主體(PACKAGE BODY):包主體則是包定義部分的具體實作,它定義了包定義部分所聲明的遊标和子程式,在包主體中還可以聲明包的私有元素。
包說明和包主體分開編譯,并作為兩部分分開的對象存放在資料庫字典中,可檢視資料字典user_source, all_source, dba_source,分别了解包說明與包主體的詳細資訊。
程式包的定義分為程式包說明定義和程式包主體定義兩部分組成。
程式包說明用于聲明包的公用元件,如變量、常量、自定義資料類型、異常、過程、函數、遊标等。包說明中定義的公有元件不僅可以在包内使用,還可以由包外其他過程、函數。但需要說明與注意的是,我們為了實作資訊的隐藏,建議不要将所有元件都放在包說明處聲明,隻應把公共元件放在包聲明部分。包的名稱是唯一的,但對于兩個包中的公有元件的名稱可以相同,這種用“包名.公有元件名“加以區分。
包體是包的具體實作細節,其實作在包說明中聲明的所有公有過程、函數、遊标等。當然也可以在包體中聲明僅屬于自己的私有過程、函數、遊标等。建立包體時,有以下幾點需要注意:
u 包體隻能在包說明被建立或編譯後才能進行建立或編譯。
u 在包體中實作的過程、函數、遊标的名稱必須與包說明中的過程、函數、遊标一緻,包括名稱、參數的名稱以及參數的模式(IN、OUT、IN OUT)。并建設按包說明中的次序定義包體中具體的實作。
u 在包體中聲明的資料類型、變量、常量都是私有的,隻能在包體中使用而不能被印刷體外的應用程式通路與使用。
u 在包體執行部分,可對包說明,包體中聲明的公有或私有變量進行初始化或其它設定。
建立程式包說明文法格式:
CREATE [OR REPLACE] PACKAGE package_name
[AUTHID {CURRENT_USER | DEFINER}]
{IS | AS}
[公有資料類型定義[公有資料類型定義]…]
[公有遊标聲明[公有遊标聲明]…]
[公有變量、常量聲明[公有變量、常量聲明]…]
[公有函數聲明[公有函數聲明]…]
[公有過程聲明[公有過程聲明]…]
END [package_name];
其中:AUTHID CURRENT_USER和AUTHID DEFINER選項說明應用程式在調用函數時所使用的權限模式,它們與CREATE FUNCTION語句中invoker_right_clause子句的作用相同。
建立程式包主體文法格式:
CREATE [OR REPLACE] PACKAGE BODY package_name
[私有資料類型定義[私有資料類型定義]…]
[私有變量、常量聲明[私有變量、常量聲明]…]
[私有異常錯誤聲明[私有異常錯誤聲明]…]
[私有函數聲明和定義[私有函數聲明和定義]…]
[私有函過程聲明和定義[私有函過程聲明和定義]…]
[公有遊标定義[公有遊标定義]…]
[公有函數定義[公有函數定義]…]
[公有過程定義[公有過程定義]…]
BEGIN
執行部分(初始化部分)
END package_name;
其中:在包主體定義公有程式時,它們必須與包定義中所聲明子程式的格式完全一緻。
與開發存儲過程類似,包的開發需要幾個步驟:
1. 将每個存儲過程調式正确;
2. 用文本編輯軟體将各個存儲過程和函數內建在一起;
3. 按照包的定義要求将內建的文本的前面加上包定義;
4. 按照包的定義要求将內建的文本的前面加上包主體;
5. 使用SQLPLUS或開發工具進行調式。
例1:建立的包為DEMO_PKG, 該包中包含一個記錄變量DEPTREC、兩個函數和一個過程。實作對dept表的增加、删除與查詢。
CREATE OR REPLACE PACKAGE DEMO_PKG
IS
DEPTREC DEPT%ROWTYPE;
--Add dept...
FUNCTION add_dept(
dept_no NUMBER,
dept_name VARCHAR2,
location VARCHAR2)
RETURN NUMBER;
--delete dept...
FUNCTION delete_dept(dept_no NUMBER)
--query dept...
PROCEDURE query_dept(dept_no IN NUMBER);
END DEMO_PKG;
包主體的建立方法,它實作上面所聲明的包定義,并在包主體中聲明一個私有變量flag和一個私有函數check_dept,由于在add_dept和remove_dept等函數中需要調用check_dpet函數,是以,在定義check_dept 函數之前首先對該函數進行聲明,這種聲明方法稱作前向聲明。
CREATE OR REPLACE PACKAGE BODY DEMO_PKG
IS
FUNCTION add_dept
(
dept_no NUMBER,
dept_name VARCHAR2,
location VARCHAR2
)
RETURN NUMBER
empno_remaining EXCEPTION; --自定義異常
PRAGMA EXCEPTION_INIT(empno_remaining, -1);
/* -1 是違反唯一限制條件的錯誤代碼 */
INSERT INTO dept VALUES(dept_no, dept_name, location);
IF SQL%FOUND THEN
RETURN 1;
END IF;
EXCEPTION
WHEN empno_remaining THEN
RETURN 0;
WHEN OTHERS THEN
RETURN -1;
END add_dept;
FUNCTION delete_dept(dept_no NUMBER)
DELETE FROM dept WHERE deptno = dept_no;
RETURN 1;
ELSE
RETURN 0;
END IF;
WHEN OTHERS THEN
RETURN -1;
END delete_dept;
PROCEDURE query_dept
(dept_no IN NUMBER)
SELECT * INTO DeptRec FROM dept WHERE deptno=dept_no;
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('溫馨提示:資料庫中沒有編碼為'||dept_no||'的部門');
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('程式運作錯誤,請使用遊标進行操作!');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE||'----'||SQLERRM);
END query_dept;
BEGIN
Null;
對包内共有元素的調用格式為:包名.元素名稱
調用DEMO_PKG包内函數對dept表進行插入、查詢和删除操作,并通過DEMO_PKG包中的記錄變量DEPTREC顯示所查詢到的資料庫資訊:
DECLARE
Var NUMBER;
Var := DEMO_PKG.add_dept(90,'HKLORB', 'HAIKOU');
IF var =-1 THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE||'----'||SQLERRM);
ELSIF var =0 THEN
DBMS_OUTPUT.PUT_LINE('溫馨提示:該部門記錄已經存在!');
ELSE
DBMS_OUTPUT.PUT_LINE('溫馨提示:添加記錄成功!');
DEMO_PKG.query_dept(90);
DBMS_OUTPUT.PUT_LINE(DEMO_PKG.DeptRec.deptno||'---'||
DEMO_PKG.DeptRec.dname||'---'||DEMO_PKG.DeptRec.loc);
var := DEMO_PKG.delete_dept(90);
IF var =-1 THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE||'----'||SQLERRM);
ELSIF var=0 THEN
DBMS_OUTPUT.PUT_LINE('溫馨提示:該部門記錄不存在!');
ELSE
DBMS_OUTPUT.PUT_LINE('溫馨提示:删除記錄成功!');
END IF;
END IF;
END;
例2: 建立包EMP_PKG,讀取emp表中的資料
--建立包說明
CREATE OR REPLACE PACKAGE EMP_PKG
TYPE emp_table_type IS TABLE OF emp%ROWTYPE
INDEX BY BINARY_INTEGER;
PROCEDURE read_emp_table (p_emp_table OUT emp_table_type);
END EMP_PKG;
--建立包體
CREATE OR REPLACE PACKAGE BODY EMP_PKG
PROCEDURE read_emp_table (p_emp_table OUT emp_table_type)
I BINARY_INTEGER := 0;
FOR emp_record IN ( SELECT * FROM emp ) LOOP
P_emp_table(i) := emp_record;
I := I + 1;
END LOOP;
END read_emp_table;
--執行
DECLARE
E_table EMP_PKG.emp_table_type;
EMP_PKG.read_emp_table(e_table);
FOR I IN e_table.FIRST ..e_table.LAST LOOP
DBMS_OUTPUT.PUT_LINE(e_table(i).empno||' '||e_table(i).ename);
END LOOP;
例3: 建立包MANAGE_EMP_PKG,對員工進行管理(新增員工、新增部門、删除指定員工、删除指定部門、增加指定員工的工資與獎金):
--建立序列從100開始,依次增加1
CREATE SEQUENCE empseq
START WITH 100
INCREMENT BY 1
ORDER NOCYCLE;
--建立序列從100開始,依次增加10
CREATE SEQUENCE deptseq
START WITH 100
INCREMENT BY 10
-- *******************************************
-- 建立包說明
-- 包 名:MANAGE_EMP_PKG
-- 功能描述:對員工進行管理(新增員工,新增部門
-- ,删除員工,删除部門,增加工資與獎金等)
-- 建立人員:胡勇
-- 建立日期:2010-05-19
-- Q Q: 80368704
-- E-mail : [email protected]
-- WebSite: http://www.cnblogs.com/huyong
-- ******************************************
CREATE OR REPLACE PACKAGE MANAGE_EMP_PKG
AS
--增加一名員工
FUNCTION hire_emp
(ename VARCHAR2, job VARCHAR2
, mgr NUMBER, sal NUMBER
, comm NUMBER, deptno NUMBER)
--新增一個部門
FUNCTION add_dept(dname VARCHAR2, loc VARCHAR2)
--删除指定員工
PROCEDURE remove_emp(empno NUMBER);
--删除指定部門
PROCEDURE remove_dept(deptno NUMBER);
--增加指定員工的工資
PROCEDURE increase_sal(empno NUMBER, sal_incr NUMBER);
--增加指定員工的獎金
PROCEDURE increase_comm(empno NUMBER, comm_incr NUMBER);
END MANAGE_EMP_PKG;--建立包說明結束
-- 建立包體
CREATE OR REPLACE PACKAGE BODY MANAGE_EMP_PKG
total_emps NUMBER; --員工數
total_depts NUMBER; --部門數
no_sal EXCEPTION;
no_comm EXCEPTION;
--增加一名員工
FUNCTION hire_emp(ename VARCHAR2, job VARCHAR2, mgr NUMBER,
sal NUMBER, comm NUMBER, deptno NUMBER)
RETURN NUMBER --傳回新增加的員工編号
IS
new_empno NUMBER(4);
BEGIN
SELECT empseq.NEXTVAL INTO new_empno FROM dual;
SELECT COUNT(*) INTO total_emps FROM emp;--目前記錄總數
INSERT INTO emp
VALUES (new_empno, ename, job, mgr, sysdate, sal, comm, deptno);
total_emps:=total_emps+1;
RETURN(new_empno);
EXCEPTION
DBMS_OUTPUT.PUT_LINE('溫馨提示:發生系統錯誤!');
END hire_emp;
RETURN NUMBER
new_deptno NUMBER(4); --部門編号
--得到一個新的自增的員工編号
SELECT deptseq.NEXTVAL INTO new_deptno FROM dual;
SELECT COUNT(*) INTO total_depts FROM dept;--目前部門總數
INSERT INTO dept VALUES (new_deptno, dname, loc);
total_depts:=total_depts;
RETURN(new_deptno);
END add_dept;
PROCEDURE remove_emp(empno NUMBER)
no_result EXCEPTION; --自定義異常
BEGIN
DELETE FROM emp WHERE emp.empno=remove_emp.empno;
IF SQL%NOTFOUND THEN
RAISE no_result;
total_emps:=total_emps - 1; --總的員工數減1
WHEN no_result THEN
DBMS_OUTPUT.PUT_LINE('溫馨提示:你需要的資料不存在!');
END remove_emp;
PROCEDURE remove_dept(deptno NUMBER)
no_result EXCEPTION; --自定義異常
exception_deptno_remaining EXCEPTION; --自定義異常
/*-2292 是違反一緻性限制的錯誤代碼*/
PRAGMA EXCEPTION_INIT(exception_deptno_remaining, -2292);
DELETE FROM dept WHERE dept.deptno=remove_dept.deptno;
total_depts:=total_depts-1; --總的部門數減1
WHEN exception_deptno_remaining THEN
DBMS_OUTPUT.PUT_LINE('溫馨提示:違反資料完整性限制!');
END remove_dept;
--給指定員工增加指定數量的工資
PROCEDURE increase_sal(empno NUMBER, sal_incr NUMBER)
curr_sal NUMBER(7, 2); --目前工資
--得到目前工資
SELECT sal INTO curr_sal FROM emp WHERE emp.empno=increase_sal.empno;
IF curr_sal IS NULL THEN
RAISE no_sal;
UPDATE emp SET sal = sal + increase_sal.sal_incr --目前工資加新增的工資
WHERE emp.empno = increase_sal.empno;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('溫馨提示:你需要的資料不存在!');
WHEN no_sal THEN
DBMS_OUTPUT.PUT_LINE('溫馨提示:此員工的工資不存在!');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('溫馨提示:發生系統錯誤!');
END increase_sal;
--給指定員工增加指定數量的獎金
PROCEDURE increase_comm(empno NUMBER, comm_incr NUMBER)
curr_comm NUMBER(7,2);
--得到指定員工的目前資金
SELECT comm INTO curr_comm
FROM emp WHERE emp.empno = increase_comm.empno;
IF curr_comm IS NULL THEN
RAISE no_comm;
UPDATE emp SET comm = comm + increase_comm.comm_incr
WHERE emp.empno=increase_comm.empno;
WHEN NO_DATA_FOUND THEN
WHEN no_comm THEN
DBMS_OUTPUT.PUT_LINE('溫馨提示:此員工的獎金不存在!');
WHEN OTHERS THEN
END increase_comm;
END MANAGE_EMP_PKG;--建立包體結束
--調用
SQL> variable empno number
SQL>execute :empno:= manage_emp_pkg.hire_emp('HUYONG',PM,1455,5500,14,10)
PL/SQL procedure successfully completed
empno
---------
105
例4:利用遊标變量建立包 CURROR_VARIBAL_PKG。由于遊标變量指是一個指針,其狀态是不确定的,是以它不能随同包存儲在資料庫中,既不能在PL/SQL包中聲明遊标變量。但在包中可以建立遊标變量參照類型,并可向包中的子程式傳遞遊标變量參數。
-- 包 名:CURROR_VARIBAL_PKG
-- 功能描述:在包中引用遊标變量
CREATE OR REPLACE PACKAGE CURROR_VARIBAL_PKG AS
TYPE DeptCurType IS REF CURSOR
RETURN dept%ROWTYPE; --強類型定義
TYPE CurType IS REF CURSOR;-- 弱類型定義
PROCEDURE OpenDeptVar(
Cv IN OUT DeptCurType,
Choice INTEGER DEFAULT 0,
Dept_no NUMBER DEFAULT 50,
Dept_name VARCHAR DEFAULT '%');
CREATE OR REPLACE PACKAGE BODY CURROR_VARIBAL_PKG
PROCEDURE OpenDeptvar(
Dept_name VARCHAR DEFAULT ‘%’)
IS
IF choice =1 THEN
OPEN cv FOR SELECT * FROM dept WHERE deptno <= dept_no;
ELSIF choice = 2 THEN
OPEN cv FOR SELECT * FROM dept WHERE dname LIKE dept_name;
OPEN cv FOR SELECT * FROM dept;
END OpenDeptvar;
END CURROR_VARIBAL_PKG;
--定義一個過程
CREATE OR REPLACE PROCEDURE UP_OpenCurType(
Cv IN OUT CURROR_VARIBAL_PKG.CurType,
FirstCapInTableName CHAR)
--CURROR_VARIBAL_PKG.CurType采用弱類型定義
--是以可以使用它定義的遊标變量打開不同類型的查詢語句
IF FirstCapInTableName = 'D' THEN
OPEN cv FOR SELECT * FROM dept;
OPEN cv FOR SELECT * FROM emp;
END UP_OpenCurType;
--定義一個應用
DeptRec Dept%ROWTYPE;
EmpRec Emp%ROWTYPE;
Cv1 CURROR_VARIBAL_PKG.deptcurtype;
Cv2 CURROR_VARIBAL_PKG.curtype;
DBMS_OUTPUT.PUT_LINE('遊标變量強類型定義應用');
CURROR_VARIBAL_PKG.OpenDeptVar(cv1, 1, 30);
FETCH cv1 INTO DeptRec;
WHILE cv1%FOUND LOOP
DBMS_OUTPUT.PUT_LINE(DeptRec.deptno||':'||DeptRec.dname);
FETCH cv1 INTO DeptRec;
CLOSE cv1;
DBMS_OUTPUT.PUT_LINE('遊标變量弱類型定義應用');
CURROR_VARIBAL_PKG.OpenDeptvar(cv2, 2, dept_name => 'A%');
FETCH cv2 INTO DeptRec;
WHILE cv2%FOUND LOOP
FETCH cv2 INTO DeptRec;
DBMS_OUTPUT.PUT_LINE('遊标變量弱類型定義應用—dept表');
UP_OpenCurType(cv2, 'D');
DBMS_OUTPUT.PUT_LINE(deptrec.deptno||':'||deptrec.dname);
FETCH cv2 INTO deptrec;
DBMS_OUTPUT.PUT_LINE('遊标變量弱類型定義應用—emp表');
UP_OpenCurType(cv2, 'E');
FETCH cv2 INTO EmpRec;
DBMS_OUTPUT.PUT_LINE(emprec.empno||':'||emprec.ename);
FETCH cv2 INTO emprec;
CLOSE cv2;
----------運作結果-------------------
遊标變量強類型定義應用
10:ACCOUNTING
20:RESEARCH
30:SALES
遊标變量弱類型定義應用
遊标變量弱類型定義應用—dept表
40:OPERATIONS
50:50abc
60:Developer
遊标變量弱類型定義應用—emp表
7369:SMITH
7499:ALLEN
7521:WARD
7566:JONES
7654:MARTIN
7698:BLAKE
7782:CLARK
7788:SCOTT
7839:KING
7844:TURNER
7876:ADAMS
7900:JAMES
7902:FORD
7934:MILLER
PL/SQL 允許對包内子程式和本地子程式進行重載。所謂重載時指兩個或多個子程式有相同的名稱,但擁有不同的參數變量、參數順序或參數資料類型。
例5:
-- 包 名:DEMO_PKG1
-- 功能描述:建立包對子程式重載進行測試
-- 建立日期:2010-05-22
CREATE OR REPLACE PACKAGE DEMO_PKG1
DeptRec dept%ROWTYPE;
V_sqlcode NUMBER;
V_sqlerr VARCHAR2(2048);
--兩個子程式名字相同,但參數類型不同
FUNCTION query_dept(dept_no IN NUMBER)
RETURN INTEGER;
FUNCTION query_dept(dept_no IN VARCHAR2)
END DEMO_PKG1;
CREATE OR REPLACE PACKAGE BODY DEMO_PKG1
FUNCTION check_dept(dept_no NUMBER)
RETURN INTEGER
deptCnt INTEGER; --指定部門号的部門數量
SELECT COUNT(*) INTO deptCnt FROM dept WHERE deptno = dept_no;
IF deptCnt > 0 THEN
RETURN 1;
RETURN 0;
END check_dept;
FUNCTION check_dept(dept_no VARCHAR2)
deptCnt INTEGER;
SELECT COUNT(*) INTO deptCnt FROM dept WHERE deptno=dept_no;
FUNCTION query_dept(dept_no IN NUMBER)
IF check_dept(dept_no) =1 THEN
END query_dept;
FUNCTION query_dept(dept_no IN VARCHAR2)
RETURN INTEGER
SELECT * INTO DeptRec FROM dept WHERE deptno = dept_no;
ORACLE 提供了一個實用工具來加密或者包裝使用者的PL/SQL,它會将使用者的PL/SQL改變為隻有ORACLE能夠解釋的代碼版本.
WRAP 實用工具位于$ORACLE_HOME/BIN.
格式為:
WRAP INAME=<input_file_name> [ONAME=<output_file_name>]
wrap iname=e:\sample.txt
注意:在加密前,請将PL/SQL程式先儲存一份,以備後用。
DROP PACKAGE [BODY] [user.]package_name;
DROP PROCEDURE OpenCurType; --删除存儲過程
--删除我們執行個體中建立的各個包
DROP PACKAGE demo_pack;
DROP PACKAGE demo_pack1;
DROP PACKAGE emp_mgmt;
DROP PACKAGE emp_package;
包與過程、函數一樣,也是存儲在資料庫中的,可以随時檢視其源碼。若有需要,在建立包時可以随時檢視更詳細的編譯錯誤。不需要的包也可以删除。
同樣,為了避免調用的失敗,在更新表的結構後,一定要記得重新編譯依賴于它的程式包。在更新了包說明或包體後,也應該重新編譯包說明與包體。文法如下:
ALTER PACKAGE package_name COMPILE [PACKAGE|BODY|SPECIFICATION];
也可以通過以下資料字典視圖檢視包的相關。
DBA_SOURCE, USER_SOURCE, USER_ERRORS, DBA-OBJECTS
如,我們可以用:select text from user_source where name = 'DEMO_PKG1';來檢視我們建立的包的源碼。
原創作品,轉貼請注明作者和出處,留此資訊。
------------------------------------------------
作者:EricHu(DB、C\S、B\S、WebService、WCF、PM等)
Q Q:80368704 E-Mail: [email protected]
本博文歡迎大家浏覽和轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,在『參考』的文章中,我會表明參考的文章來源,尊重他人版權。若您發現我侵犯了您的版權,請及時與我聯系。