Oracle 8i 缺乏原生 OS 命令執行功能。OEM 作業排程參數固定、缺乏彈性。利用 DBMS_PIPE 實現資料庫與外部進程雙向通訊,滿足動態執行需求。
CREATE OR REPLACE PACKAGE BODY daemon AS
FUNCTION execute_system(
command VARCHAR2,
timeout NUMBER DEFAULT 10
) RETURN NUMBER IS
status NUMBER;
result VARCHAR2(20);
command_code NUMBER;
pipe_name VARCHAR2(30);
BEGIN
/* 產生唯一回覆管道名稱 */
pipe_name := DBMS_PIPE.UNIQUE_SESSION_NAME;
/* 封裝請求訊息:指令類型、回覆管道、實際命令 */
DBMS_PIPE.PACK_MESSAGE('SYSTEM');
DBMS_PIPE.PACK_MESSAGE(pipe_name);
DBMS_PIPE.PACK_MESSAGE(command);
/* 發送至守護進程監聽管道 */
status := DBMS_PIPE.SEND_MESSAGE('daemon', timeout);
IF status <> 0 THEN
RAISE_APPLICATION_ERROR(-20010,
'Execute_system: Error while sending. Status = ' || status);
END IF;
/* 後續接收結果邏輯見下篇 */
END execute_system;
END daemon;
| 函數/程序 | 用途 |
|---|---|
DBMS_PIPE.UNIQUE_SESSION_NAME | 產生唯一管道名,格式:ORA$PIPE$<SID>.<SERIAL#> |
DBMS_PIPE.PACK_MESSAGE | 將資料封裝進區域緩衝區,支援 VARCHAR2、NUMBER、DATE、RAW |
DBMS_PIPE.SEND_MESSAGE | 發送緩衝區內容至指定管道,回傳 0=成功、1=逾時、2=緩衝區過大、3=中斷 |
DBMS_PIPE.RECEIVE_MESSAGE | 從管道讀取訊息至緩衝區 |
DBMS_PIPE.UNPACK_MESSAGE | 從緩衝區解析資料至變數,順序必須與 PACK 一致 |
DECLARE
v_result NUMBER;
BEGIN
v_result := daemon.execute_system('rm -f /tmp/old_export.dmp', 30);
DBMS_OUTPUT.PUT_LINE('Command exit code: ' || v_result);
END;
EXECUTE ON daemon 權限僅授予可信角色DBMS_SCHEDULER 外部作業,具備憑證隔離與審計