PL-SQL 包的創建和應用



PL-SQL 包的創建和應用

①簡介
    包是一組相關過程、函數、變量、常量和遊標等PL/SQL程序設計元素的組合,它具有面向對象程序設計語言的特點,是對這些PL/SQL 程序設計元素的封裝。
包類似於C++和JAVA語言中的類,其中變量相當於類中的成員變量,過程和函數相當於類方法。
把相關的模塊歸類成爲包,可使開發人員利用面向對象的方法進行存儲過程的開發,從而提高系統性能。
    與類相同,包中的程序元素也分爲公用元素和私用元素兩種,這兩種元素的區別是他們允許訪問的程序範圍不同,即它們的作用域不同。
公用元素不僅可以被包中的函數、過程所調用,也可以被包外的PL/SQL程序訪問,而私有元素只能被包內的函數和過程序所訪問。
    在PL/SQL程序設計中,使用包不僅可以使程序設計模塊化,對外隱藏包內所使用的信息(通過使用私用變量),而且可以提高程序的執行效率。
因爲,當程序首次調用包內函數或過程時,ORACLE將整個包調入內存,當再次訪問包內元素時,ORACLE直接從內存中讀取,而不需要進行磁盤I/O操作,
從而使程序執行效率得到提高。

一個包由兩個分開的部分組成:
包定義(PACKAGE):包定義部分聲明包內數據類型、變量、常量、遊標、子程序和異常錯誤處理等元素,這些元素爲包的公有元素。
包主體(PACKAGE BODY):包主體則是包定義部分的具體實現,它定義了包定義部分所聲明的遊標和子程序,在包主體中還可以聲明包的私有元素。
包定義和包主體分開編譯,並作爲兩部分分開的對象存放在數據庫字典中,詳見數據字典user_source, all_source, dba_source.

②包的定義
包定義的語法如下:
1.創建包定義:
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 BODYpackage_name
{IS| AS}
    [私有數據類型定義[私有數據類型定義]…]
    [私有變量、常量聲明[私有變量、常量聲明]…]
    [私有子程序聲明和定義[私有子程序聲明和定義]…]
    [公有遊標定義[公有遊標定義]…]
    [公有子程序定義[公有子程序定義]…]
BEGIN
    PL/SQL 語句
END[package_name];
其中:在包主體定義公有程序時,它們必須與包定義中所聲明子程序的格式完全一致。
對包內共有元素的調用格式爲:包名.元素名稱

③子程序重載
PL/SQL 允許對包內子程序和本地子程序進行重載。
所謂重載時指兩個或多個子程序有相同的名稱,但擁有不同的參數變量、參數順序或參數數據類型。

④刪除包
可以使用DROP PACKAGE命令對不需要的包進行刪除,語法如下:
DROP PACKAGE [BODY] [user.]package_name;

⑤包的管理
DBA_SOURCE, USER_SOURCE, USER_ERRORS, DBA-OBJECTS


⑥例子:
創建的包爲demo_pack, 該包中包含一個記錄變量DeptRec、兩個函數和一個過程。
CREATE OR REPLACE PACKAGE demo_pack
IS
    DeptRec dept%ROWTYPE;
    FUNCTION add_dept(dept_no NUMBER, dept_name VARCHAR2, location VARCHAR2)
        RETURN NUMBER;
    FUNCTION remove_dept(dept_no NUMBER)
        RETURN NUMBER;
    PROCEDURE query_dept(dept_no IN NUMBER);
END demo_pack

包主體的創建方法,它實現上面所聲明的包定義
CREATE OR REPLACE PACKAGE BODY demo_pack
IS
    --函數定義
    FUNCTION add_dept(dept_no NUMBER, dept_name VARCHAR2, location VARCHAR2)
        RETURN NUMBER
    IS
        empno_remaining EXCEPTION;
        PRAGMA EXCEPTION_INIT(empno_remaining, -1);
        /* -1 是違反唯一約束條件的錯誤代碼*/
    BEGIN
        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 remove_dept(dept_no NUMBER)
       RETURN NUMBER
   IS
   BEGIN
       DELETE FROM dept WHERE deptno=dept_no;
       IF SQL%FOUND THEN
          RETURN 1;
       ELSE
          RETURN 0;
       END IF;
   EXCEPTION
       WHEN OTHERS THEN
          RETURN -1;
   END remove_dept;


   --過程定義
   PROCEDURE query_dept(dept_no IN NUMBER)
   IS
   BEGIN
       SELECT * INTO DeptRec FROM dept WHERE deptno=dept_no;
   EXCEPTION
       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;
END demo_pack;


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章