套件將邏輯相關的程序、函數、變數、游標、例外等封裝為單一命名模組,類似 C++/Java 的 Class 概念,是大型 PL/SQL 應用架構的基石。
| 部分 | 關鍵字 | 內容 | 可見性 |
|---|---|---|---|
| 套件規格 | PACKAGE | 型別、變數、常數、游標、子程式**宣告**、例外 | Public(外部可見) |
| 套件主體 | PACKAGE BODY | 子程式**實作**、私有變數/型別/子程式 | Private(僅內部可見) |
規格與主體**獨立編譯**,分別儲存於資料字典,修改主體不影響依賴規格的物件,避免級聯重編譯。
-- 套件規格 CREATE OR REPLACE PACKAGE pkg_name IS v_comm NUMBER := 200; -- 公有變數 TYPE rec_person IS RECORD (...); -- 公有型別 TYPE ref_cur IS REF CURSOR; -- 公有游標型別 FUNCTION get_year_sal(p_sal NUMBER) RETURN NUMBER; PROCEDURE add_person(p_id NUMBER, p_name VARCHAR2, p_age NUMBER, p_pwd VARCHAR2); PROCEDURE get_person(p_id IN NUMBER, p_cur OUT ref_cur); END pkg_name; -- 套件主體 CREATE OR REPLACE PACKAGE BODY pkg_name IS FUNCTION get_year_sal(p_sal NUMBER) RETURN NUMBER IS BEGIN RETURN (p_sal + v_comm) * 12; END; PROCEDURE add_person(p_id NUMBER, p_name VARCHAR2, p_age NUMBER, p_pwd VARCHAR2) IS BEGIN INSERT INTO person VALUES (p_id, p_name, p_age, p_pwd); COMMIT; END; PROCEDURE get_person(p_id IN NUMBER, p_cur OUT ref_cur) IS BEGIN OPEN p_cur FOR SELECT id, username, age, password FROM person; END; END pkg_name;
DECLARE
v_cur pkg_name.ref_cur;
v_rec pkg_name.rec_person;
BEGIN
DBMS_OUTPUT.PUT_LINE('年薪=' || pkg_name.get_year_sal(12000));
pkg_name.get_person(1, v_cur);
LOOP
FETCH v_cur INTO v_rec;
EXIT WHEN v_cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('姓名=' || v_rec.rusername);
END LOOP;
pkg_name.add_person(10001, 'zhangsan', 20, '1343');
END;
| 套件 | 核心用途 |
|---|---|
DBMS_ALERT | 非同步事件通知,觸發器發送警報給應用程式。 |
DBMS_OUTPUT | PUT_LINE/GET_LINE 除錯輸出,SQL*Plus 需 SET SERVEROUTPUT ON。 |
DBMS_PIPE | Session 間命名管道通訊(PACK_MESSAGE/SEND_MESSAGE/RECEIVE_MESSAGE/UNPACK_MESSAGE)。 |
UTL_FILE | OS 文字檔讀寫(FOPEN/PUT_LINE/GET_LINE/FCLOSE),需建立 DIRECTORY 物件授權。 |
UTL_HTTP | PL/SQL 呼叫 HTTP/HTTPS,抓取網頁或呼叫 Web Service,回傳 HTML/JSON/XML。 |
CREATE PACKAGE ... END;,再跑 CREATE PACKAGE BODY ... END;。