PL/SQL - Package

在Java中你可以在程式碼最上方加上package來封裝此程式碼,C#中定義namespace來封裝,在PL/SQL中也有定義Package達到封裝效果。


在前一篇Procedure與Function有提到,建立Procedure或Function後會建立在Oracle的Procedure與Function目錄裡,如果我有一個Procedure功能與已存在的Procedure類似,但又有點不一樣,Oracle又不允許在Procedure目錄下建立相同名稱的Procedure,這時候就要靠Package來把相同名稱的Procedure分開。Package也有分類的意思,將相關功能模組封裝在同一個Package內可提高聚合性。

要定義一個Package需要兩個部分:Package Specification與Package Body。Package Specification定義了此Package內所有的成員,例如:Procedure與Function,就像C++的Header檔一樣。這裡定義的Procedure與Function只要擺定義即可不需要放實作的內容,在Specification的成員都是對外公開Public,如果有Private成員不須在此定義。


Package Specification 語法架構:


CREATE OR REPLACE package_name
AS
      --成員定義區
      procudure_header();
      function_header() RETURN DATATYPE;
END package_name;

Package Body為放置成員Spec的詳細實作區,在建立Package時要先有Specification才可以有Body,你可以將Spec與Body分成兩個檔案撰寫也可以撰寫在同一個檔案裡。另外如果有Private成員就要加在Body裡,不須定義在Specification。Private成員要注意的是它必須宣告在呼叫他的程式之前,因為Oracle compile時是從上到下,所以如果在compile時找不到呼叫的procedure時就會發生錯誤

Package Body 語法架構:

CREATE OR REPLACE BODY package_name
AS
      --Private 成員
      private_procedure_function;

      --Public 成員實作區
      procedure_body;
      function_body;
END package_name;

Package Body裡的procedure_body與function_body就和Procedure與Function的語法架構一樣,只差在不用在前面加CREATE OR REPLACE。


下面限量將上一篇Procedure與Function的範例程式碼封裝在一個Package裡。

PKGTESTOUTPUTSTR Spec:


CREATE OR REPLACE PACKAGE EBS.PKGTESTOUTPUTSTR AS

  FUNCTION CombineTwoString(pi_str1 IN VARCHAR2,
    pi_str2 IN VARCHAR2
  ) RETURN VARCHAR2;
  
  PROCEDURE OutputStringConcate(
    pi_str1 IN VARCHAR2,
    pi_str2 IN VARCHAR2,
    po_strConcate OUT VARCHAR2
  );

END PKGTESTOUTPUTSTR;

PKGTESTOUTPUTSTR Body:


CREATE OR REPLACE PACKAGE BODY EBS.PKGTESTOUTPUTSTR AS

FUNCTION CombineTwoString
(
    pi_str1 IN VARCHAR2,
    pi_str2 IN VARCHAR2
) RETURN VARCHAR2
IS
    lv_combine VARCHAR2(32);
BEGIN
    DBMS_OUTPUT.PUT_LINE('COMBINETOWSTRING-' || pi_str1);
    DBMS_OUTPUT.PUT_LINE('COMBINETOWSTRING-' || pi_str2);
    lv_combine := pi_str1 || pi_str2;
    DBMS_OUTPUT.PUT_LINE('COMBINETOWSTRING-' || lv_combine);
    RETURN lv_combine;
END CombineTwoString;

PROCEDURE OutputStringConcate
(
    pi_str1 IN VARCHAR2,
    pi_str2 IN VARCHAR2,
    po_strConcate OUT VARCHAR2
) 
IS
BEGIN
    DBMS_OUTPUT.PUT_LINE('OUTPUTSTRINGCONCATE-' || pi_str1);
    DBMS_OUTPUT.PUT_LINE('OUTPUTSTRINGCONCATE-' || pi_str2);
    po_strConcate := pi_str1 || pi_str2;
    DBMS_OUTPUT.PUT_LINE('OUTPUTSTRINGCONCATE-' || po_strConcate);
END;

END PKGTESTOUTPUTSTR;

在最後來提一下使用Package的好處,在書中有提到,使用Package可幫助開發人員進行封裝, 結構化與資料隱藏,將邏輯相關的功能Group起來幫助開發人員連想記憶,且在效能上會提升,因為當Package Compile後會Keep在Memory中,之後叫用時會較快速。



參考來源:

Learning Oracle PL/SQL - OReilly電子書

留言