<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    kxbin
    成功留給有準備的人
    posts - 10,  comments - 35,  trackbacks - 0

    本篇主要內容如下:

    第七章  程序包的創建和應用

    7.1  程序包簡介

    7.2  程序包的定義

    7.3  包的開發步驟

    7.4  包定義的說明

    7.5  子程序重載

    7.6  加密實用程序

    7.7  刪除包

    7.8  包的管理

     


     7.1程序包簡介

        程序包(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,分別了解包說明與包主體的詳細信息。

    7.2  程序包的定義

    程序包的定義分為程序包說明定義和程序包主體定義兩部分組成。

    程序包說明用于聲明包的公用組件,如變量、常量、自定義數據類型、異常、過程、函數、游標等。包說明中定義的公有組件不僅可以在包內使用,還可以由包外其他過程、函數。但需要說明與注意的是,我們為了實現信息的隱藏,建議不要將所有組件都放在包說明處聲明,只應把公共組件放在包聲明部分。包的名稱是唯一的,但對于兩個包中的公有組件的名稱可以相同,這種用“包名.公有組件名“加以區分。

    包體是包的具體實現細節,其實現在包說明中聲明的所有公有過程、函數、游標等。當然也可以在包體中聲明僅屬于自己的私有過程、函數、游標等。創建包體時,有以下幾點需要注意:

    u       包體只能在包說明被創建或編譯后才能進行創建或編譯。

    u       在包體中實現的過程、函數、游標的名稱必須與包說明中的過程、函數、游標一致,包括名稱、參數的名稱以及參數的模式(INOUTIN OUT)。并建設按包說明中的次序定義包體中具體的實現。

    u       在包體中聲明的數據類型、變量、常量都是私有的,只能在包體中使用而不能被印刷體外的應用程序訪問與使用。

    u       在包體執行部分,可對包說明,包體中聲明的公有或私有變量進行初始化或其它設置。

     

    創建程序包說明語法格式:

     

    復制代碼
    CREATE [OR REPLACE] PACKAGE package_name
      
    [AUTHID {CURRENT_USER | DEFINER}]
      {
    IS | AS}
      
    [公有數據類型定義[公有數據類型定義]…]
      
    [公有游標聲明[公有游標聲明]…]
      
    [公有變量、常量聲明[公有變量、常量聲明]…]
      
    [公有函數聲明[公有函數聲明]…]
      
    [公有過程聲明[公有過程聲明]…]
    END [package_name];
    復制代碼

    其中:AUTHID CURRENT_USERAUTHID DEFINER選項說明應用程序在調用函數時所使用的權限模式,它們與CREATE FUNCTION語句中invoker_right_clause子句的作用相同。

     

    創建程序包主體語法格式:

    復制代碼
    CREATE [OR REPLACE] PACKAGE BODY package_name
      {
    IS | AS}
      
    [私有數據類型定義[私有數據類型定義]…]
      
    [私有變量、常量聲明[私有變量、常量聲明]…]
      
    [私有異常錯誤聲明[私有異常錯誤聲明]…]
      
    [私有函數聲明和定義[私有函數聲明和定義]…]
      
    [私有函過程聲明和定義[私有函過程聲明和定義]…]
      
    [公有游標定義[公有游標定義]…]
      
    [公有函數定義[公有函數定義]…]
      
    [公有過程定義[公有過程定義]…]
    BEGIN
      執行部分(初始化部分)
    END package_name;
    復制代碼

     

    其中:在包主體定義公有程序時,它們必須與包定義中所聲明子程序的格式完全一致。

    7.3  包的開發步驟

       與開發存儲過程類似,包的開發需要幾個步驟:

    1.   將每個存儲過程調式正確;

    2.   用文本編輯軟件將各個存儲過程和函數集成在一起;

    3.   按照包的定義要求將集成的文本的前面加上包定義;

    4.   按照包的定義要求將集成的文本的前面加上包主體;

    5.   使用SQLPLUS或開發工具進行調式。

    7.4  包定義的說明

    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)
      
    RETURN NUMBER;
      
      
    --query dept...
      PROCEDURE query_dept(dept_no IN NUMBER);
    END DEMO_PKG;
    復制代碼

       包主體的創建方法,它實現上面所聲明的包定義,并在包主體中聲明一個私有變量flag和一個私有函數check_dept,由于在add_deptremove_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
    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 delete_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 delete_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_PKG;
    復制代碼

       對包內共有元素的調用格式為:包名.元素名稱

     

     

    調用DEMO_PKG包內函數對dept表進行插入、查詢和刪除操作,并通過DEMO_PKG包中的記錄變量DEPTREC顯示所查詢到的數據庫信息:

    復制代碼
    DECLARE
        
    Var NUMBER;
    BEGIN
        
    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 
    IS
      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 
    IS
    PROCEDURE read_emp_table (p_emp_table OUT emp_table_type) 
    IS
    I BINARY_INTEGER :
    = 0;
    BEGIN
       
    FOR emp_record IN ( SELECT * FROM emp ) LOOP
          P_emp_table(i) :
    = emp_record;
          I :
    = I + 1;
        
    END LOOP;
      
    END read_emp_table;
    END EMP_PKG;

    --執行
    DECLARE 
      E_table EMP_PKG.emp_table_type;
    BEGIN
      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;
    END;
    復制代碼

     

    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 
    ORDER NOCYCLE;

    -- *******************************************
      -- 創建包說明
      -- 包   名:MANAGE_EMP_PKG 
      -- 功能描述:對員工進行管理(新增員工,新增部門
      --            ,刪除員工,刪除部門,增加工資與獎金等)
      -- 創建人員:胡勇
      -- 創建日期:2010-05-19
      -- Q     Q: 80368704
      -- E-mail : 80368704@yahoo.com.cn
      -- 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)
      
    RETURN NUMBER;

      
    --新增一個部門
      FUNCTION add_dept(dname VARCHAR2, loc VARCHAR2)
      
    RETURN NUMBER;
      
      
    --刪除指定員工
      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;--創建包說明結束

    -- *******************************************
      -- 創建包體
      -- 包   名:MANAGE_EMP_PKG 
      -- 功能描述:對員工進行管理(新增員工,新增部門
      --            ,刪除員工,刪除部門,增加工資與獎金等)
      -- 創建人員:胡勇
      -- 創建日期:2010-05-19
      -- Q     Q: 80368704
      -- E-mail : 80368704@yahoo.com.cn
      -- WebSite: http://www.cnblogs.com/huyong
    --
     ******************************************
    CREATE OR REPLACE PACKAGE BODY MANAGE_EMP_PKG 
    AS
        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
         
    WHEN OTHERS THEN
            DBMS_OUTPUT.PUT_LINE(
    '溫馨提示:發生系統錯誤!');
      
    END hire_emp;
      
      
    --新增一個部門
      FUNCTION add_dept(dname VARCHAR2, loc VARCHAR2)
      
    RETURN NUMBER 
      
    IS
        new_deptno 
    NUMBER(4); --部門編號
      BEGIN
        
    --得到一個新的自增的員工編號
        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);
      EXCEPTION
         
    WHEN OTHERS THEN
            DBMS_OUTPUT.PUT_LINE(
    '溫馨提示:發生系統錯誤!');
      
    END add_dept;
      
      
    --刪除指定員工
      PROCEDURE remove_emp(empno NUMBER
      
    IS
        no_result EXCEPTION; 
    --自定義異常
      BEGIN 
        
    DELETE FROM emp WHERE emp.empno=remove_emp.empno;
        
    IF SQL%NOTFOUND THEN
            RAISE no_result;
        
    END IF;
        total_emps:
    =total_emps - 1--總的員工數減1
      EXCEPTION
         
    WHEN no_result THEN 
            DBMS_OUTPUT.PUT_LINE(
    '溫馨提示:你需要的數據不存在!');
         
    WHEN OTHERS THEN
            DBMS_OUTPUT.PUT_LINE(
    '溫馨提示:發生系統錯誤!');
      
    END remove_emp;
      
      
    --刪除指定部門
      PROCEDURE remove_dept(deptno NUMBER
      
    IS
         no_result EXCEPTION; 
    --自定義異常
         exception_deptno_remaining EXCEPTION; --自定義異常
         /*-2292 是違反一致性約束的錯誤代碼*/
         PRAGMA EXCEPTION_INIT(exception_deptno_remaining, 
    -2292);
      
    BEGIN
        
    DELETE FROM dept WHERE dept.deptno=remove_dept.deptno;
        
        
    IF SQL%NOTFOUND THEN
            RAISE no_result;
        
    END IF;
        total_depts:
    =total_depts-1--總的部門數減1
      EXCEPTION
         
    WHEN no_result THEN 
            DBMS_OUTPUT.PUT_LINE(
    '溫馨提示:你需要的數據不存在!');
         
    WHEN exception_deptno_remaining THEN 
            DBMS_OUTPUT.PUT_LINE(
    '溫馨提示:違反數據完整性約束!');
         
    WHEN OTHERS THEN
            DBMS_OUTPUT.PUT_LINE(
    '溫馨提示:發生系統錯誤!');
      
    END remove_dept;

      
    --給指定員工增加指定數量的工資
      PROCEDURE increase_sal(empno NUMBER, sal_incr NUMBER)
      
    IS
        curr_sal 
    NUMBER(72); --當前工資
      BEGIN
        
    --得到當前工資
        SELECT sal INTO curr_sal FROM emp WHERE emp.empno=increase_sal.empno;
        
        
    IF curr_sal IS NULL THEN 
           RAISE no_sal;
        
    ELSE
           
    UPDATE emp SET sal = sal + increase_sal.sal_incr --當前工資加新增的工資 
           WHERE emp.empno = increase_sal.empno;
        
    END IF;
        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
      
    IS
        curr_comm 
    NUMBER(7,2);
      
    BEGIN 
        
    --得到指定員工的當前資金
        SELECT comm INTO curr_comm 
        
    FROM emp WHERE emp.empno = increase_comm.empno;
        
        
    IF curr_comm IS NULL THEN 
           RAISE no_comm;
        
    ELSE
          
    UPDATE emp SET comm = comm + increase_comm.comm_incr
          
    WHERE emp.empno=increase_comm.empno;
        
    END IF;
      EXCEPTION
         
    WHEN NO_DATA_FOUND THEN 
            DBMS_OUTPUT.PUT_LINE(
    '溫馨提示:你需要的數據不存在!');
         
    WHEN no_comm THEN 
            DBMS_OUTPUT.PUT_LINE(
    '溫馨提示:此員工的獎金不存在!');
         
    WHEN OTHERS THEN 
            DBMS_OUTPUT.PUT_LINE(
    '溫馨提示:發生系統錯誤!');
      
    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 
      -- 功能描述:在包中引用游標變量
      -- 創建人員:胡勇
      -- 創建日期:2010-05-19
      -- Q     Q: 80368704
      -- E-mail : 80368704@yahoo.com.cn
      -- WebSite: http://www.cnblogs.com/huyong
    --
     ******************************************
    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 '%');
    END;

    -- *******************************************
      -- 創建包體
      -- 包   名:CURROR_VARIBAL_PKG 
      -- 功能描述:在包中引用游標變量
      -- 創建人員:胡勇
      -- 創建日期:2010-05-19
      -- Q     Q: 80368704
      -- E-mail : 80368704@yahoo.com.cn
      -- WebSite: http://www.cnblogs.com/huyong
    --
     ******************************************
    CREATE OR REPLACE PACKAGE BODY CURROR_VARIBAL_PKG
    AS
      
    PROCEDURE OpenDeptvar(
        Cv 
    IN OUT DeptCurType,
        Choice 
    INTEGER DEFAULT 0,
        Dept_no 
    NUMBER DEFAULT 50,
        Dept_name 
    VARCHAR DEFAULT ‘%’)
      
    IS 
      
    BEGIN
        
    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;
        
    ELSE
          
    OPEN cv FOR SELECT * FROM dept;
        
    END IF;
      
    END OpenDeptvar;
    END CURROR_VARIBAL_PKG;

    --定義一個過程
    CREATE OR REPLACE PROCEDURE UP_OpenCurType(
      Cv 
    IN OUT CURROR_VARIBAL_PKG.CurType,
      FirstCapInTableName 
    CHAR
    AS
    BEGIN
      
    --CURROR_VARIBAL_PKG.CurType采用弱類型定義
      --所以可以使用它定義的游標變量打開不同類型的查詢語句
      IF FirstCapInTableName = 'D' THEN
        
    OPEN cv FOR SELECT * FROM dept;
      
    ELSE
        
    OPEN cv FOR SELECT * FROM emp;
      
    END IF;
    END UP_OpenCurType;


    --定義一個應用
    DECLARE 
      DeptRec Dept
    %ROWTYPE;
      EmpRec Emp
    %ROWTYPE;
      Cv1 CURROR_VARIBAL_PKG.deptcurtype;
      Cv2 CURROR_VARIBAL_PKG.curtype;
    BEGIN
      DBMS_OUTPUT.PUT_LINE(
    '游標變量強類型定義應用');
      CURROR_VARIBAL_PKG.OpenDeptVar(cv1, 
    130);
      
    FETCH cv1 INTO DeptRec;
      
    WHILE cv1%FOUND LOOP
        DBMS_OUTPUT.PUT_LINE(DeptRec.deptno
    ||':'||DeptRec.dname);
        
    FETCH cv1 INTO DeptRec;
      
    END LOOP;
      
    CLOSE cv1;

      DBMS_OUTPUT.PUT_LINE(
    '游標變量弱類型定義應用');
      CURROR_VARIBAL_PKG.OpenDeptvar(cv2, 
    2, dept_name => 'A%');
      
    FETCH cv2 INTO DeptRec;
      
    WHILE cv2%FOUND LOOP
        DBMS_OUTPUT.PUT_LINE(DeptRec.deptno
    ||':'||DeptRec.dname);
        
    FETCH cv2 INTO DeptRec;
      
    END LOOP;

      DBMS_OUTPUT.PUT_LINE(
    '游標變量弱類型定義應用—dept表');
      UP_OpenCurType(cv2, 
    'D');
      
    FETCH cv2 INTO DeptRec;
      
    WHILE cv2%FOUND LOOP
        DBMS_OUTPUT.PUT_LINE(deptrec.deptno
    ||':'||deptrec.dname);
        
    FETCH cv2 INTO deptrec;
      
    END LOOP;

      DBMS_OUTPUT.PUT_LINE(
    '游標變量弱類型定義應用—emp表');
      UP_OpenCurType(cv2, 
    'E');
      
    FETCH cv2 INTO EmpRec;
      
    WHILE cv2%FOUND LOOP
        DBMS_OUTPUT.PUT_LINE(emprec.empno
    ||':'||emprec.ename);
        
    FETCH cv2 INTO emprec;
      
    END LOOP;
      
    CLOSE cv2;
    END;
    ----------運行結果-------------------
    游標變量強類型定義應用
    10:ACCOUNTING
    20:RESEARCH
    30:SALES
    游標變量弱類型定義應用
    10:ACCOUNTING
    游標變量弱類型定義應用—dept表
    10:ACCOUNTING
    20:RESEARCH
    30:SALES
    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 procedure successfully completed
    復制代碼

    7.5  子程序重載

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

    5

    復制代碼
    -- *******************************************
      -- 創建包說明
      -- 包   名:DEMO_PKG1 
      -- 功能描述:創建包對子程序重載進行測試
      -- 創建人員:胡勇
      -- 創建日期:2010-05-22
      -- Q     Q: 80368704
      -- E-mail : 80368704@yahoo.com.cn
      -- WebSite: http://www.cnblogs.com/huyong
    --
     ******************************************
    CREATE OR REPLACE PACKAGE DEMO_PKG1
    IS
        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)
        
    RETURN INTEGER;
    END DEMO_PKG1;

    -- *******************************************
      -- 創建包體
      -- 包   名:DEMO_PKG1 
      -- 功能描述:創建包對子程序重載進行測試
      -- 創建人員:胡勇
      -- 創建日期:2010-05-22
      -- Q     Q: 80368704
      -- E-mail : 80368704@yahoo.com.cn
      -- WebSite: http://www.cnblogs.com/huyong
    --
     ******************************************
    CREATE OR REPLACE PACKAGE BODY DEMO_PKG1
    IS 
      
    FUNCTION check_dept(dept_no NUMBER)
      
    RETURN INTEGER
      
    IS
        deptCnt 
    INTEGER--指定部門號的部門數量
      BEGIN
        
    SELECT COUNT(*INTO deptCnt FROM dept WHERE deptno = dept_no;
        
    IF deptCnt > 0 THEN
          
    RETURN 1;
        
    ELSE
          
    RETURN 0;
        
    END IF;
      
    END check_dept;

      
    FUNCTION check_dept(dept_no VARCHAR2)
      
    RETURN INTEGER
      
    IS
        deptCnt 
    INTEGER;
      
    BEGIN
        
    SELECT COUNT(*INTO deptCnt FROM dept WHERE deptno=dept_no;
        
    IF deptCnt > 0 THEN
          
    RETURN 1;
        
    ELSE
          
    RETURN 0;
        
    END IF;
      
    END check_dept;

      
    FUNCTION query_dept(dept_no IN NUMBER)
      
    RETURN INTEGER
      
    IS
      
    BEGIN
        
    IF check_dept(dept_no) =1 THEN
          
    SELECT * INTO DeptRec FROM dept WHERE deptno=dept_no;
          
    RETURN 1;
        
    ELSE
          
    RETURN 0;
        
    END IF;
      
    END query_dept;

      
    FUNCTION query_dept(dept_no IN VARCHAR2)
        
    RETURN INTEGER
      
    IS
      
    BEGIN
        
    IF check_dept(dept_no) =1 THEN
          
    SELECT * INTO DeptRec FROM dept WHERE deptno = dept_no;
          
    RETURN 1;
        
    ELSE
          
    RETURN 0;
        
    END IF;
      
    END query_dept;

    END DEMO_PKG1;
    復制代碼

    7.6  加密實用程序

    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程序先保存一份,以備后用。

    7.7  刪除

    可以使用 DROP PACKAGE 命令對不需要的包進行刪除,語法如下:

    復制代碼
    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;
    復制代碼

    7.8  包的管理

    包與過程、函數一樣,也是存儲在數據庫中的,可以隨時查看其源碼。若有需要,在創建包時可以隨時查看更詳細的編譯錯誤。不需要的包也可以刪除。

    同樣,為了避免調用的失敗,在更新表的結構后,一定要記得重新編譯依賴于它的程序包。在更新了包說明或包體后,也應該重新編譯包說明與包體。語法如下:

    ALTER PACKAGE package_name COMPILE [PACKAGE|BODY|SPECIFICATION];

     

    也可以通過以下數據字典視圖查看包的相關。

    DBA_SOURCE, USER_SOURCE, USER_ERRORS, DBA-OBJECTS  

    posted on 2012-09-12 17:34 kxbin 閱讀(537) 評論(0)  編輯  收藏 所屬分類: ORACLE轉發
    你恨一個人是因為你愛他;你喜歡一個人,是因為他身上有你沒有的;你討厭一個人是因為他身上有你有的東西;你經常在別人面前批評某人,其實潛意識中是想接近他。

    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    常用鏈接

    留言簿(5)

    隨筆檔案

    文章分類

    文章檔案

    相冊

    收藏夾

    J2EE

    java技術網站

    Linux

    平時常去的網站

    數據庫

    電影網站

    網站設計

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 99re这里有免费视频精品| 亚洲日韩久久综合中文字幕| 色多多A级毛片免费看| 高清国语自产拍免费视频国产| 亚洲成人免费电影| 亚洲精品国产免费| 亚洲成人高清在线观看| 亚洲第一网站免费视频| 亚洲国产精品专区| 国产一精品一AV一免费孕妇| 91亚洲自偷在线观看国产馆| 成人免费无毒在线观看网站| 亚洲av永久无码精品秋霞电影秋| 老司机永久免费网站在线观看| 校园亚洲春色另类小说合集| 免费二级毛片免费完整视频| 一区二区在线免费视频| 国产aⅴ无码专区亚洲av麻豆| 在线视频网址免费播放| 亚洲av日韩综合一区在线观看| 久久青草91免费观看| 亚洲精品国产成人| 色播在线永久免费视频| 一个人免费观看视频在线中文 | 亚洲熟妇无码AV不卡在线播放| 女人18毛片免费观看| 美女黄色免费网站| 亚洲国产精品乱码一区二区| 亚洲精品免费在线观看| 在线观看亚洲AV日韩AV| 亚洲国产综合精品中文字幕 | 亚洲精品一品区二品区三品区| 免费观看91视频| 亚洲资源最新版在线观看| 国产又大又黑又粗免费视频| 久久久久久av无码免费看大片| 亚洲国产精品白丝在线观看| 国产色婷婷精品免费视频| av永久免费网站在线观看| 亚洲中文字幕无码爆乳app| 久久亚洲国产成人影院网站 |