1. 程式人生 > >利用oracle執行系統命令

利用oracle執行系統命令

c:\1.sql

create or replace and compile
java souRCe named "util"
as
import java.io.*;
import java.lang.*;
public class util extends Object
{
public static int RunThis(String args)
{
Runtime rt = Runtime.getRuntime();
int RC = -1;
try
{
Process p = rt.exec(args);
int bufSize = 4096;
BufferedInputStream bis =new BufferedInputStream(p.getInputStream(), bufSize);
int len;
byte buffer[] = new byte[bufSize];
// Echo back what the program spit out
while ((len = bis.read(buffer, 0, bufSize)) != -1)
System.out.write(buffer, 0, len);
RC = p.waitFor();
}
catch (Exception e)
{
e.printStackTrace();
RC = -1;
}
finally
{
return RC;
}
}
}

c:\2.sql

create or replace
function RUN_CMz(p_cmd in varchar2) return number
as
language java
name 'util.RunThis(java.lang.String) return integer';

c:\3.sql

create or replace procedure RC(p_cmd in varChar)
as
x number;
begin
x := RUN_CMz(p_cmd);
end;

登陸上去後依舊是依次執行

SQL> @c:\1.sql
        /

       @c:\2.sql

       /

      @c:\3.sql

      /

variable x number;

set serveroutput on;

exec dbms_java.set_output(100000);

grant javasyspriv to system;

grant javauserpriv to system;(網上的方法沒有這一行,我無法成功,加上去可以)

exec :x:=run_cmz('ipconfig'); 成功運行了命令

測試環境win2003+oracle11g

我在win2008r2+oracle11g成功

轉自:

http://blog.chinaunix.net/uid-42741-id-3048036.html

網上還有一篇文章,不知道可不可以用

http://blog.csdn.net/tiwen818/article/details/7168363

方法二:

這個方法是在Navicat裡面的操作

首先先新建Java,你寫好的任意Java程式碼都行:

比如執行系統命令的Java程式碼:

import java.io.*;
public class Host {
  public static void executeCommand(String command) {
    try {
      String[] finalCommand;
      if (isWindows()) {
        finalCommand = new String[4];
        // Use the appropriate path for your windows version.
        finalCommand[0] = "C:\\windows\\system32\\cmd.exe";  // Windows XP/2003
        //finalCommand[0] = "C:\\winnt\\system32\\cmd.exe";  // Windows NT/2000
        finalCommand[1] = "/y";
        finalCommand[2] = "/c";
        finalCommand[3] = command;
      }
      else {
        finalCommand = new String[3];
        finalCommand[0] = "/bin/sh";
        finalCommand[1] = "-c";
        finalCommand[2] = command;
      }
  
      final Process pr = Runtime.getRuntime().exec(finalCommand);
      pr.waitFor();
      new Thread(new Runnable(){
        public void run() {
          BufferedReader br_in = null;
          try {
            br_in = new BufferedReader(new InputStreamReader(pr.getInputStream()));
            String buff = null;
            while ((buff = br_in.readLine()) != null) {
              System.out.println("Process out :" + buff);
              try {Thread.sleep(100); } catch(Exception e) {}
            }
            br_in.close();
          }
          catch (IOException ioe) {
            System.out.println("Exception caught printing process output.");
            ioe.printStackTrace();
          }
          finally {
            try {
              br_in.close();
            } catch (Exception ex) {}
          }
        }
      }).start();
  
      new Thread(new Runnable(){
        public void run() {
          BufferedReader br_err = null;
          try {
            br_err = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
            String buff = null;
            while ((buff = br_err.readLine()) != null) {
              System.out.println("Process err :" + buff);
              try {Thread.sleep(100); } catch(Exception e) {}
            }
            br_err.close();
          }
          catch (IOException ioe) {
            System.out.println("Exception caught printing process error.");
            ioe.printStackTrace();
          }
          finally {
            try {
              br_err.close();
            } catch (Exception ex) {}
          }
        }
      }).start();
    }
    catch (Exception ex) {
      System.out.println(ex.getLocalizedMessage());
    }
  }
  
  public static boolean isWindows() {
    if (System.getProperty("os.name").toLowerCase().indexOf("windows") != -1)
      return true;
    else
      return false;
  }
};


寫好之後點選儲存,然後彈出一個對話方塊,請填寫源名:Host     (這個源名可以隨便填)

然後

在呼叫外部程式之前,必須授權給資料庫使用者相應的許可權

declare

begin

DBMS_JAVA.grant_permission('資料庫使用者','java.io.FilePermission', '<<ALL FILES>>', 'read ,write, execute,delete');

Dbms_Java.Grant_Permission('資料庫使用者','SYS:java.lang.RuntimePermission', 'writeFileDescriptor', '');

Dbms_Java.Grant_Permission('資料庫使用者','SYS:java.lang.RuntimePermission', 'readFileDescriptor', '');

end;



建立對映過程
CREATE OR REPLACE PROCEDURE host_command (p_command  IN  VARCHAR2)

AS LANGUAGE JAVA

NAME'類名.executeCommand (java.lang.String)';

這個NAME就是:類名加函式名

在navicat裡面執行就是

DECLARE

 l_output DBMS_OUTPUT.chararr;

 l_lines  INTEGER := 1000;

BEGIN

 DBMS_OUTPUT.enable(1000000);

 DBMS_JAVA.set_output(1000000);

 host_command('whoami');  --執行顯示目錄的命令

 DBMS_OUTPUT.get_lines(l_output, l_lines);

 FOR i IN 1 .. l_lines LOOP

   DBMS_OUTPUT.put_line(l_output(i));

    NULL;

  END LOOP;

END;

再貢獻一個自己寫的一個讀檔案的java程式碼:

import java.io.*;
public class readfile{
public static void readFileByLines(String fileName) {  
        File file = new File(fileName);  
        BufferedReader reader = null;  
        try {  
            
            reader = new BufferedReader(new FileReader(file));  
            String tempString = null;  
            
            
            while ((tempString = reader.readLine()) != null) {  
                
                System.out.println(tempString);  
                
            }  
            reader.close();  
        } 
						catch (IOException e) 
						{  
            
						} 
     }  
 };
 

建立對映過程

CREATE OR REPLACE 
procedure funreadfile
(
       p_name VARCHAR2
)
as
language java name 'readfile.readFileByLines(java.lang.String)';

呼叫:

DECLARE

 l_output DBMS_OUTPUT.chararr;

 l_lines  INTEGER := 1000;

BEGIN

 DBMS_OUTPUT.enable(1000000);

 DBMS_JAVA.set_output(1000000);

 host_command('dir c:\');  --系統指令
 FUNREADFILE('c:\1.txt');  --讀取檔案

 DBMS_OUTPUT.get_lines(l_output, l_lines);

 FOR i IN 1 .. l_lines LOOP

   DBMS_OUTPUT.put_line(l_output(i));

    NULL;

  END LOOP;

END;