Oracle PL/SQL之 Package介紹

starive發表於2014-02-08

Package 包



一 包的組成

    • 包頭(package):包頭部分申明包內資料型別,常量,變數,遊標,子程式和異常錯誤處理,這些元素為包的公有元素。
    • 包主體(package body):包主體則是包定義部分的具體實現,它負責為包頭中所宣告子程式提供具體的實現,在包主體中還可以宣告包的私有元素。
    • 包頭和包主體分開編譯,並作為兩個分開的物件分別存放在資料庫字典中。


二  包的語法規則

包頭的語法如下:


  1. create or replace package 包名
  2. As | IS
  3.           procedure 過程名();
  4.           Function 函式名() return 資料型別;
  5.            變數定義;
  6.           異常定義;
  7.           游標定義;
  8.           ...........
  9.           ...........
  10. End 包名;



包體建立的語法:

  1. create or replace Package Body 包名
  2. As | IS
  3.             Procedure 過程定義;
  4.             Procedure 過程定義;
  5.              Function 函式定義;
  6.             Function 函式定義;
  7.                 .........;

  8. end 包名;



三 包的應用與舉例

下面是student 和SC表的定義:

  1. CREATE TABLE Student
  2.        (Sno CHAR(9) PRIMARY KEY,
  3.         Sname CHAR(20) NOT NULL, 
  4.         Ssex CHAR(4),
  5.         Sage SMALLINT,
  6.         Sdept CHAR(20)) tablespace starivespace;


  7. CREATE TABLE SC
  8.          (Sno CHAR(9) NOT NULL,
  9.           Cno CHAR(6) NOT NULL, 
  10.           Grade SMALLINT,
  11.           PRIMARY KEY (Sno,Cno),
  12.           constraint f1 FOREIGN KEY (Sno) REFERENCES Student(Sno),
  13.           FOREIGN KEY (Cno) REFERENCES Course(Cno)
  14.       ) tablespace starivespace

        例項:定義一個包,實現如果功能: 輸入學號,分別返回該學生的所在系和相應的選課成績(如果有多門成績,那麼就輸出多門成績)。

  定義包頭

  1. create or replace
  2.   package sdept_or_grade as
  3.    procedure print_sdept(psno char);
  4.    procedure print_grade(psno char);
  5.    end;
  6.    /


  7. 程式包已建立。


建立包體
  1. create or replace
  2. package body sdept_or_grade 
  3. as
  4. procedure print_sdept(psno char) as
  5.     psdept student.sdept%type;
  6. begin
  7.      select sdept into psdept
  8.     from student
  9.     where sno=psno;
  10.     dbms_output.put_line(psdept);
  11.     exception
  12.     when no_data_found then
  13.         dbms_output.put_line(\'Invalid student number\');
  14. end;
  15. procedure print_grade(psno char) as
  16.     pgrade SC.grade%type;
  17. cursor printgrade is select grade into pgrade
  18.     from sc
  19.     where sno=psno;

  20. begin
  21.     open printgrade;
  22.    loop
  23.     fetch printgrade into pgrade;
  24.         dbms_output.put_line(pgrade);
  25. exit when printgrade%notfound;
  26. end loop;
  27. close printgrade;
  28. exception
  29.     when no_data_found then
  30.         dbms_output.put_line(\'Invalid student number\');
  31. end;
  32. end;
  33. /



程式包體已建立。




獲取結果

  1. SQL> set serveroutput on;
  2. SQL>
  3. SQL> execute sdept_or_grade.print_sdept(\'0201\');
  4. cs

  5. PL/SQL 過程已成功完成。

  6. SQL>
  7. SQL> execute sdept_or_grade.print_grade(\'0201\');
  8. 89
  9. 64
  10. 50
  11. 50

  12. PL/SQL 過程已成功完成。




四  心得體會


從以上例子,和以往在實際應用中額經驗,對包的優點總結如下:


第一  包可以簡化應用程式設計:程式包的說明部分和包體部分可以分別建立各編譯。體現在以下三個方面:

1)        在設計一個應用程式,只建立各編譯程式包的說明部分,然後再編寫引用該程式包的PL/SQL塊。

2)        當完成整個應用程式的整體框架後,再回頭來定義包體部分。只要不改變包的說明部分,就可以單獨除錯、增加或替換包體的內容,這不會影響其他的應用程式。

3)        更新包的說明後必須重新編譯引用包的應用程式,但更新包體,則不需重新編譯引用包的應用程式,以快速進行應用程式的原形開發。

第二   模組化:可將邏輯相關的PL/SQL塊或元素等組織在一起,用名稱來唯一標識程式包。把一個大的功能模組劃分人適當個數小的功能模組,分別完成各自的功能。這樣組織的程式包都易於編寫,易於理解更易於管理。

第三     效率高:程式包在應用程式第一次呼叫程式包中的某個元素時,ORACLE將把整個程式包載入到記憶體中,當再次訪問程式包中的元素時,將直接從內在中讀取,而不需要進行磁碟I/O操作而影響速度,同時位於內在中的程式包可被同一會話期間的其它應用程式共享。因此,程式包增加了重用性並改善了多使用者、多應用程式環境的效率。
最後   還有提到一點: 資訊隱藏。因為包中的元素可以分為公有元素和私有元素。公有元素可被程式包內的過程、函式等的訪問,還可以被包外的PL/SQL訪問。但對於私有元素只能被包內的過程、函式等訪問。對於使用者,只需知道包的說明,不用瞭解包休的具體細節(由於時間關係,明天繼續貼出“資訊隱藏”的相關例子)。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26435490/viewspace-1078212/,如需轉載,請註明出處,否則將追究法律責任。

相關文章