全部產品
Search
文件中心

PolarDB:CREATE PACKAGE

更新時間:Nov 15, 2024

CREATE PACKAGE定義一個包。CREATE OR REPLACE PACKAGE將會建立一個新包或者替換一個已有的定義。包是組織和封裝資料庫應用程式邏輯的重要工具。通過合理設計和使用包,可以提高代碼的可維護性、重用性和效能。

簡介

CREATE PACKAGE語句用於建立儲存包的規範,儲存包是儲存在資料庫中的相關過程、函數及其他程式對象的封裝集合。包規範聲明了這些對象,而隨後的包體則定義了這些對象的具體實現。

如果建立包時包含schema名稱,則將在指定的schema中建立。否則,將在當前schema中建立。除非要更新現有包的定義,否則新包的名稱不能與同一schema中的任何現有包匹配。在這種情況下,請使用CREATE OR REPLACE PACKAGE。建立該過程的使用者將成為包的所有者。

包是將過程和函數建立為獨立模組對象的替代方案。

文法

CREATE [ OR REPLACE ] PACKAGE <package_name>
    [ AUTHID { DEFINER | CURRENT_USER } ]
    { IS | AS }
    [ <declaration>; ] [, ...]
[   {
        PROCEDURE <proc_name>
        [ (<argname> [ IN | IN OUT | OUT ] <argtype> [ DEFAULT <value> ]
        [, ...]) ];
        [ PRAGMA RESTRICT_REFERENCES(<proc_name>,
        { RNDS | RNPS | TRUST | WNDS | WNPS } [, ... ] ); ]
        |
        FUNCTION <func_name>
        [ (<argname> [ IN | IN OUT | OUT ] <argtype> [ DEFAULT <value> ]
        [, ...]) ]
        RETURN <rettype> [ DETERMINISTIC ];
        [ PRAGMA RESTRICT_REFERENCES(<func_name>,
        { RNDS | RNPS | TRUST | WNDS | WNPS } [, ... ] ); ]
    }
] [, ...]
END [ <name> ]

參數說明

參數

描述

package_name

要建立的包的名稱(可選schema限定)。

DEFINER | CURRENT_USER

指定使用何種許可權訪問包中引用的資料庫物件。取值範圍如下:

  • DEFINER(預設值):使用包所有者許可權訪問包中引用的資料庫物件。

  • CURRENT_USER:使用執行包的目前使用者的許可權訪問包中引用的資料庫物件。

declaration

公開變數、類型、遊標或REF CURSOR聲明。

proc_name

公用預存程序名稱。

argname

參數名稱。

IN | IN OUT | OUT

參數模式。

argtype

程式參數的資料類型。

DEFAULT value

輸入參數的預設值。

func_name

公用函數名稱。

rettype

返回資料類型。

DEFERMININTIC

DETERMINISTICIMMUTABLE的同義字。DETERMINISTIC過程不能修改資料庫,並且在給定相同的參數值時總是達到相同的結果。它不執行資料庫尋找,只使用其參數列表中直接存在的資訊。如果包含此子句,則可以立即用過程值的所有常量參數替換過程的任何調用。

RNDS | RNPS | TRUST | WNDS | WNPS

為實現相容性提供該參數,請忽略。

結構

包頭定義了包的介面部分,包括公開的常量、變數、類型、過程和函數等。其他程式單元可以引用包頭中聲明的對象。

CREATE OR REPLACE PACKAGE Employee_Pkg AS
    -- 常量
    MAX_SALARY CONSTANT NUMBER := 100000;

    -- 過程聲明
    PROCEDURE Add_Employee(
        p_emp_id     IN NUMBER,
        p_first_name IN VARCHAR2,
        p_last_name  IN VARCHAR2,
        p_salary     IN NUMBER
    );

    PROCEDURE Update_Salary(
        p_emp_id     IN NUMBER,
        p_new_salary IN NUMBER
    );

    -- 函式宣告
    FUNCTION Get_Employee_Name(
        p_emp_id IN NUMBER
    ) RETURN VARCHAR2;
END Employee_Pkg;

注意事項

  • 依賴管理:修改包頭會導致依賴包的所有對象需要重新編譯,請謹慎進行變更。

  • 錯誤處理:在包中妥善處理異常,避免未捕獲的異常導致程式中斷。

  • 效能最佳化:合理使用包的私人變數和緩衝機制,提高效能。

  • 安全性:通過包的許可權控制限制對敏感性資料和功能的訪問。

  • 命名規範:遵循統一的命名規範,便於代碼理解和維護。

使用說明

一旦包成功建立並編譯完成,即可在PL/SQL代碼中引用包內的過程、函數等。

調用包中的過程和函數

  • 調用過程。

    BEGIN
        Employee_Pkg.Add_Employee(
            p_emp_id     => 1001,
            p_first_name => '張',
            p_last_name  => '三',
            p_salary     => 50000
        );
    END;
  • 調用函數

    DECLARE
        v_emp_name VARCHAR2(100);
    BEGIN
        v_emp_name := Employee_Pkg.Get_Employee_Name(1001);
        DBMS_OUTPUT.PUT_LINE('員工姓名: ' || v_emp_name);
    END;

包同名函數處理

Oracle支援包中的同名函數,實作類別似多態的行為,對應的PolarDB也支援相同的行為。

說明

PolarDB PostgreSQL版Oracle文法相容 2.0在核心小版本2.0.14.26.0新增建立IN參數相同,OUT參數不同的同名函數。若叢集的核心小版本低於該版本且需要使用該功能,請將核心小版本升級到2.0.14.26.0或以上版本。查詢和升級核心小版本,請參見版本管理

CREATE OR REPLACE PACKAGE Employee_Pkg AS
    -- 常量
    MAX_SALARY CONSTANT NUMBER := 100000;

    -- 函式宣告
    FUNCTION Get_Employee_Name(
        p_emp_id IN NUMBER
    ) RETURN VARCHAR2;

    -- 同名函數
    FUNCTION Get_Employee_Name(
        p_emp_id IN NUMBER,
        res_info OUT text
    ) RETURN VARCHAR2;
END Employee_Pkg;

包函數使用包變數作為參數預設值

說明

PolarDB PostgreSQL版Oracle文法相容 2.0在核心小版本2.0.14.26.0新增使用包變數做函數參數預設值。若叢集的核心小版本低於該版本且需要使用該功能,請將核心小版本升級到2.0.14.26.0或以上版本。查詢和升級核心小版本,請參見版本管理

CREATE OR REPLACE PACKAGE test_package AS
    a NUMBER := 1;
    b NUMBER := 2;
END my_package;

CREATE OR REPLACE PACKAGE my_package AS
    FUNCTION add_numbers(x NUMBER default test_package.a, y NUMBER default test_package.b) RETURN NUMBER;
    PROCEDURE print_message(msg VARCHAR2);
END my_package;

維護和更新包

說明

如需向包中添加新的公開對象,必須對包頭和包體進行相應的修改。修改包頭將導致依賴該包的所有對象失效,需要重新進行編譯。如果僅對包體中的實現進行修改(不影響包頭),則無需重新編譯依賴對象。詳細的包體SQL語句介紹請參考CREATE PACKAGE BODY

向包中添加新函數。

  1. 修改包頭。

    CREATE OR REPLACE PACKAGE Employee_Pkg AS
       -- 現有聲明
       FUNCTION Get_Employee_Department(p_emp_id IN NUMBER) RETURN VARCHAR2;
    END Employee_Pkg;
  2. 修改包體。

    CREATE OR REPLACE PACKAGE BODY Employee_Pkg AS
       -- 現有實現
    
       FUNCTION Get_Employee_Department(p_emp_id IN NUMBER) RETURN VARCHAR2 IS
           v_department VARCHAR2(100);
       BEGIN
           SELECT department
           INTO v_department
           FROM employees
           WHERE emp_id = p_emp_id;
           RETURN v_department;
       EXCEPTION
           WHEN NO_DATA_FOUND THEN
               RETURN 'Not Assigned';
       END Get_Employee_Department;
    END Employee_Pkg;

相關參考

完整的包建立和使用樣本請參考樣本