首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Oracle 在數據庫內執行 OS 命令的三種方法對比

     編輯:Oracle 資料庫相關知識

方法一:SQL*Plus HOST 命令 (最簡單、僅限交互)

SQL> HOST NET USER
SQL> ! LS -L       -- Unix/Linux 別名

優點:無需額外對象、即時交互。缺點:僅 SQL*Plus 客戶端可用,不可在 PL/SQL / 排程任務中調用。

方法二:外部過程 + msvcrt.dll (Windows、舊版常見、風險高)

CREATE OR REPLACE LIBRARY exec_shell AS 'C:\WINDOWS\SYSTEM32\MSVCRT.DLL';
/
CREATE OR REPLACE PACKAGE oracmd IS
  PROCEDURE exec(cmd VARCHAR2);
END;
/
CREATE OR REPLACE PACKAGE BODY oracmd IS
  PROCEDURE exec(cmd VARCHAR2) IS EXTERNAL
    NAME "system" LIBRARY exec_shell LANGUAGE C;
END;
/
-- 調用
EXEC oracmd.exec('DIR > C:\ORACLE.TXT');

實測失敗:ORA-28595: Extproc agent: DLL path invalid。需配置 listener.ora EXTPROC、tnsnames.ora、extproc.ora、權限、EXTPROC_DLLS=ONLY 等,維護成本極大,不推薦生產使用。

方法三:Java Stored Procedure (跨平台、標準、推薦)

1. 加載 Java 源碼

CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED "Util" AS
import java.io.*;
public class Util {
  public static int runCmd(String cmd) {
    try {
      Process p = Runtime.getRuntime().exec(cmd);
      BufferedInputStream in = new BufferedInputStream(p.getInputStream(), 4096);
      byte[] buf = new byte[4096]; int len;
      while ((len = in.read(buf)) != -1) System.out.write(buf, 0, len);
      return p.waitFor();
    } catch (Exception e) { e.printStackTrace(); return -1; }
  }
};
/

2. 發布為 PL/SQL 函數/過程

CREATE OR REPLACE FUNCTION run_cmd(p_cmd VARCHAR2) RETURN NUMBER
AS LANGUAGE JAVA NAME 'Util.runCmd(java.lang.String) return int';
/
CREATE OR REPLACE PROCEDURE rc(p_cmd VARCHAR2) AS
  x NUMBER;
BEGIN x := run_cmd(p_cmd); END;
/

3. 權限授予與調用

GRANT JAVASYSPRIV TO ;
GRANT JAVAUSERPRIV TO ;
EXEC DBMS_JAVA.SET_OUTPUT(100000);
VARIABLE x NUMBER;
EXEC :x := run_cmd('IPCONFIG');  -- Windows
EXEC :x := run_cmd('LS -L');     -- Linux

優點:純 Java、跨平台、標準接口、可捕獲標準輸出。缺點:需 JVM、CREATE JAVA 權限、OS 層面命令需在白名單/容器內允許。

安全建議

  • 嚴格控制 CREATE JAVA/CREATE LIBRARY 權限,僅 DBA 擁有。
  • 命令參數化,防止注入(如 Runtime.exec(new String[]{cmd, arg1, arg2}))。
  • 審計所有調用記錄,納入合規檢查。
  • 優先考慮外部調度器 (cron, Windows Task, Jenkins) 替代數據庫內執行 OS 命令。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved