天天看點

[強烈推薦]ORACLE PL/SQL程式設計詳解之七:程式包的建立與應用(聰明在于學習,天才在于積累!)

程式包的建立與應用(聰明在于學習,天才在于積累!)

——通過知識共享樹立個人品牌。

繼上七篇:

<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&gt; variable empno number

SQL&gt;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 &lt;= 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 =&gt; '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 &gt; 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=&lt;input_file_name&gt; [ONAME=&lt;output_file_name&gt;]

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]

本博文歡迎大家浏覽和轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,在『參考』的文章中,我會表明參考的文章來源,尊重他人版權。若您發現我侵犯了您的版權,請及時與我聯系。