隨著存儲過程、函數增長,預設全置於 USER_PROCEDURES 扁平列表中,管理極其困難。Package 提供 **命名空間隔離** 與 **邏輯模組化**,將相關程序、函數、游標、型別、變數、常數、例外集中封裝,極大降低維護成本。
| 部分 | 關鍵字 | 角色 | 可見性 |
|---|---|---|---|
| 規格 | PACKAGE | 宣告公共介面:程序/函數簽名、公共變數/常數/型別/游標/例外 | 外部可引用 |
| 主體 | PACKAGE BODY | 實作規格中宣告的程序/函數;定義私有變數/常數/型別/游標/例外 | 僅主體內部可見 |
規格 = 介面契約,主體 = 實作細節。修改主體不影響呼叫端(只要規格不變),實現**介面與實作分離**。
CREATE OR REPLACE PACKAGE pack_test AS
-- 公共變數/常數
g_batch_no VARCHAR2(10);
c_max_retry CONSTANT NUMBER := 3;
-- 公共型別
TYPE emp_rec IS RECORD (emp_id VARCHAR2(10), sal NUMBER(20,2));
-- 公共游標
CURSOR emp_cur RETURN emp_rec;
-- 公共例外
e_invalid_sal EXCEPTION;
-- 公共程序/函數
FUNCTION hire_emp (p_name VARCHAR2, p_age NUMBER, p_sex VARCHAR2) RETURN NUMBER;
PROCEDURE fire_emp (p_emp_id VARCHAR2);
END pack_test;
CREATE OR REPLACE PACKAGE BODY pack_test AS
-- 私有常數/變數(外部不可見)
c_default_sal CONSTANT NUMBER := 5000;
g_total_cnt NUMBER := 0;
-- 游標實作
CURSOR emp_cur RETURN emp_rec IS
SELECT emp_id, salary FROM employee;
-- 函數實作
FUNCTION hire_emp (p_name VARCHAR2, p_age NUMBER, p_sex VARCHAR2) RETURN NUMBER IS
BEGIN
DBMS_OUTPUT.PUT_LINE('Hire: '||p_name||' Age:'||p_age||' Sex:'||p_sex);
g_total_cnt := g_total_cnt + 1;
RETURN 1;
END;
-- 程序實作
PROCEDURE fire_emp (p_emp_id VARCHAR2) IS
BEGIN
DBMS_OUTPUT.PUT_LINE('Fire: '||p_emp_id);
g_total_cnt := g_total_cnt - 1;
END;
-- 初始化區塊(首次引用包時自動執行一次)
BEGIN
g_total_cnt := 0;
END pack_test;
| 目標 | 命令 |
|---|---|
| 整包編譯 | ALTER PACKAGE pack_test COMPILE PACKAGE; |
| 僅規格 | ALTER PACKAGE pack_test COMPILE SPECIFICATION; |
| 僅主體 | ALTER PACKAGE pack_test COMPILE BODY; |
查看錯誤:SHOW ERRORS PACKAGE pack_test; / SHOW ERRORS PACKAGE BODY pack_test;
EXECUTE pack_test.fire_emp('3008732');i := pack_test.hire_emp('Jelly',23,'M'); pack_test.fire_emp('660045214');呼叫格式:package_name.element_name,與 Java/C# 命名空間呼叫一致。
DROP PACKAGE BODY pack_test; -- 僅刪主體,規格保留
DROP PACKAGE pack_test; -- 刪除整包(規格+主體)
需具備 DROP ANY PROCEDURE 權限。
同一 Package 內允許**同名程序/函數**,參數**個數或型別不同**。規則:
PROCEDURE proc(p VARCHAR2);
PROCEDURE proc(p NUMBER); -- 合法重載
PROCEDURE proc(p IN VARCHAR2);
PROCEDURE proc(p OUT VARCHAR2); -- 非法:僅模式不同
PKG_AR (應收)、PKG_GL (總帳)、PKG_COMMON (共用工具)。BEGIN ... END package_name;。Package 是 PL/SQL 的「類」機制:**規格定介面、主體藏實作、權限分公私、支援重載**。善用 Package 將散亂程式單元模組化,是大型 PL/SQL 專案可維護性的關鍵。