利用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;