首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

Oracle 利用 DBMS_PIPE 在 PL/SQL 中呼叫作業系統指令

     編輯:Oracle 資料庫基礎

Oracle 8i 無內建指令直接呼叫 OS 命令,但可透過 DBMS_PIPE 實現資料庫進程與外部守護進程通訊,達到在 SQL/預存程序中執行 OS 指令的目的。本文提供完整 DAEMON 套件實作碼。

架構原理

  1. 資料庫端:封裝指令 → 寫入 daemon 管道 → 等待回覆。
  2. 外部守護進程(C/Pro*C/Shell 腳本):讀取 daemon 管道 → 執行 OS 指令 → 將結果寫入唯一回覆管道(DBMS_PIPE.UNIQUE_SESSION_NAME)。
  3. 資料庫端:讀取回覆管道 → 解包結果碼 → 返回呼叫端。

資料庫端套件實作

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);
    -- 發送指令至 daemon 管道
    status := DBMS_PIPE.SEND_MESSAGE('daemon', timeout);
    IF status <> 0 THEN
      RAISE_APPLICATION_ERROR(-20010, 'Send error: ' || status);
    END IF;
    -- 接收執行結果
    status := DBMS_PIPE.RECEIVE_MESSAGE(pipe_name, timeout);
    IF status <> 0 THEN
      RAISE_APPLICATION_ERROR(-20011, 'Receive error: ' || status);
    END IF;
    DBMS_PIPE.UNPACK_MESSAGE(result);
    IF result <> 'done' THEN
      RAISE_APPLICATION_ERROR(-20012, 'Done not received');
    END IF;
    DBMS_PIPE.UNPACK_MESSAGE(command_code);
    DBMS_OUTPUT.PUT_LINE('System command executed. result=' || command_code);
    RETURN command_code;
  END execute_system;

  PROCEDURE stop(timeout NUMBER DEFAULT 10) IS
    status NUMBER;
  BEGIN
    DBMS_PIPE.PACK_MESSAGE('STOP');
    status := DBMS_PIPE.SEND_MESSAGE('daemon', timeout);
    IF status <> 0 THEN
      RAISE_APPLICATION_ERROR(-20030, 'Stop send error: ' || status);
    END IF;
  END stop;

END daemon;
/
SHOW ERRORS;

外部守護進程需實作邏輯

  • 持續 RECEIVE_MESSAGE('daemon')。
  • 解包 type、return_pipe、command。
  • 若 type='SYSTEM' 執行命令,將 'done' 與返回碼 PACK_MESSAGE 後 SEND_MESSAGE(return_pipe)。
  • 若 type='STOP' 則結束迴圈。

使用範例

-- 在 SQL*Plus 或預存程序中
BEGIN
  daemon.execute_system('ls -l /tmp > /tmp/ls.out');
END;
/
-- 或查詢
SELECT daemon.execute_system('date') FROM dual;

安全與限制提醒

  • 需嚴格控制 EXECUTE ON daemon 權限,防止任意命令注入。
  • 外部守護進程需以具備足夠 OS 權限的帳號運行,通常為 oracle 軟體擁有者。
  • 10g+ 可改用 DBMS_SCHEDULER 建立 EXECUTABLE 類型作業,原生支援 OS 指令執行,更安全便捷。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved