利用oracle执行系统命令,利用oracle存储过程执行操作系统命令(转)
以下方法在WINNT,LINUX下的oracle9i上测试通过,java过程调用系统命令
首先给使用java存储过程的用户授予一定的权限
<>表示所有文件,也可以单独指定文件。
r w e d表示四种操作
Code:
Dbms_Java.Grant_Permission('HR',
'java.io.FilePermission', '<>',
'read ,write, execute, delete');
Dbms_Java.Grant_Permission('HR',
'java.io.FilePermission', 'd:aa.bat',
'read ,write, execute, delete');
dbms_java.grant_permission
('HR',
'java.lang.RuntimePermission',
'*',
'writeFileDescriptor' );
end;
/
PL/SQL procedure successfully completed.
See
... timePermission.html
... rityPermission.html
s/api/java/io/FilePermission.html
and
... 53/perf.htm#1001971
From the “Java Developer’s Guide”, Part No. A81353-01, Chapter 5:
Table 5?1 Permission Types
n java.util.PropertyPermission
n java.io.SerializablePermission
n java.io.FilePermission
n java.net.NetPermission
n java.net.SocketPermission
n java.lang.RuntimePermission
n java.lang.reflect.ReflectPermission
n java.security.SecurityPermission
n oracle.aurora.rdbms.security.PolicyTablePermission
n oracle.aurora.security.JServerPermission
相关的java类如下
SQL> connect hr/hr@ts
已连接。
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;
}
}
}
/
Java created.
建立函数
create or replace
function RUN_CMD(p_cmd in varchar2) return number
as
language java
name 'Util.RunThis(java.lang.String) return integer';
/
Function created.
建立一过程调用函数
create or replace procedure RC(p_cmd in varchar2)
as
x number;
begin
x := run_cmd(p_cmd);
end;
/
Procedure created.
SQL> variable x number;
SQL> set serveroutput on
SQL> exec dbms_java.set_output(100000);
PL/SQL procedure successfully completed.
可以执行相应的命令和bat文件
SQL> exec :x := RUN_CMD('ipconfig');
Windows 2000 IP Configuration
Ethernet adapter 本地连接
:
Connection-specific DNS Suffix . :
IP Address. . . . . . . . . . . . : 172.18.25.102
Subnet Mask . . . . . . .
. . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 172.18.25.1
PL/SQL 过程已成功完成。
也可以执行服务器上的bat文件
SQL> exec :x := RUN_CMD('c:aa.bat');
c:oracleora92DATABASE>cmd /c
c:oracleora92DATABASE>dir
Volume in drive C is 本地磁盘
Volume Serial Number is 5CE1-2622
Directory of c:oracleora92DATABASE
2004-05-15 15:47 .
2004-05-15 15:47 ..
2002-12-24 20:13 archive
1998-09-09 18:31 31,744 oradba.exe
2004-05-08 11:48 568 OraDim.Log
2004-03-17 11:53 1,536 PWDweblish.ora
2004-05-15 15:47 1,871,872 SNCFWEBLISH.ORA
2003-12-29 13:24 2,560 SPFILEWEBLISH.ORA
2004-05-08 11:48 12,852 sqlnet.log
6 File(s) 1,921,132 bytes
3 Dir(s) 7,141,621,760 bytes free
-----------------
c:aa.bat如下:
cmd /c
dir
以下是利用proc实现:
在Oracle 8i中,往往会出现要在存储过程中运行操作系统命令的情况.一般来说,利用Oracle Enterprise Manager设定作业时可以达到这个目的.但是由于OEM在设定作业缺乏灵活性,设定的作业的参数是固定的.在实际应用当中往往需要在SQL语句当中运行需要随时运行操作系统命令.Oracle 8i没有直接运行OS命令的语句,我们可以利用DBMS_PIPE程序包实现这一要求.
DBMS_PIPE通过创建管道,可以让至少两个进程进行通信.Oracle的管道与操作系统的管道在概念上有相同的地方,但是在实现机制不同.
下面介绍实现具体步骤:
1 创建一个程序包,姑且起名叫DAEMON,SQL语句如下:
/*创建daemon程序包*/CREATEORREPLACEPACKAGE BODY daemonAS/*execute_system是实现运行os命令的函数*/FUNCTIONexecute_system(commandVARCHAR2,
timeoutNUMBERDEFAULT10)RETURNNUMBERISstatusNUMBER;
resultVARCHAR2(20);
command_codeNUMBER;
pipe_nameVARCHAR2(30);BEGINpipe_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);IFstatus<>0THENRAISE_APPLICATION_ERROR(-20010,'Execute_system: Error while sending. Status ='||status);ENDIF;
status :=DBMS_PIPE.RECEIVE_MESSAGE(pipe_name, timeout);IFstatus<>0THENRAISE_APPLICATION_ERROR(-20011,'Execute_system: Error while receiving.
Status ='||status);ENDIF;/*获取返回结果*/DBMS_PIPE.UNPACK_MESSAGE(result);IFresult<>'done'THENRAISE_APPLICATION_ERROR(-20012,'Execute_system: Done not received.');ENDIF;
DBMS_PIPE.UNPACK_MESSAGE(command_code);
DBMS_OUTPUT.PUT_LINE('System command executed. result ='||command_code);RETURNcommand_code;ENDexecute_system;/*stop是让daemon停止*/PROCEDUREstop(timeoutNUMBERDEFAULT10)ISstatusNUMBER;BEGINDBMS_PIPE.PACK_MESSAGE('STOP');
status :=DBMS_PIPE.SEND_MESSAGE('daemon', timeout);IFstatus<>0THENRAISE_APPLICATION_ERROR(-20030,'stop: error while sending. status ='||status);ENDIF;ENDstop;ENDdaemon;
通过Sql*Plus运行以上语句,将为当前用户创建daemon程序包.
2 创建在OS上运行的守护进程,监听由上面的daemon程序包发来的要求执行os命令的语句.以下Pro*C的代码,必须由pro*c先进行预编译.
#include
#include
EXECSQL INCLUDE SQLCA;
EXECSQLBEGINDECLARESECTION;char*uid="scott/tiger";/*在这个地方改为你自己访问的用户,密码,服务名*/intstatus;
VARCHARcommand[20];
VARCHARvalue[2000];
VARCHARreturn_name[30];
EXECSQLENDDECLARESECTION;
void
connect_error()
{
charmsg_buffer[512];
intmsg_length;
intbuffer_size=512;
EXECSQL WHENEVER SQLERRORCONTINUE;
sqlglm(msg_buffer,&buffer_size,&msg_length);
printf("Daemon errorwhileconnecting:n");
printf("%.*sn", msg_length, msg_buffer);
printf("Daemon quitting.n");
exit(1);
}
void
sql_error()
{
charmsg_buffer[512];
intmsg_length;
intbuffer_size=512;
EXECSQL WHENEVER SQLERRORCONTINUE;
sqlglm(msg_buffer,&buffer_size,&msg_length);
printf("Daemon errorwhileexecuting:n");
printf("%.*sn", msg_length, msg_buffer);
printf("Daemon continuing.n");
}
main()
{
EXECSQL WHENEVER SQLERROR DO connect_error();
EXECSQL CONNECT :uid;
printf("Daemon connected.n");
EXECSQL WHENEVER SQLERROR DO sql_error();
printf("Daemon waiting...n");
while(1) {
EXECSQLEXECUTEBEGIN/*接收deamon发来的字符*/:status :=DBMS_PIPE.RECEIVE_MESSAGE('daemon');
IF:status=0THEN/*取出字符*/DBMS_PIPE.UNPACK_MESSAGE(:command);
ENDIF;
END;
END-EXEC;
IF(status==0)
{
command.arr[command.len]='';/*如果是stop,该进程就退出*/IF(!strcmp((char*) command.arr, "STOP"))
{
printf("Daemon exiting.n");
break;
}
ELSEIF(!strcmp((char*) command.arr, "SYSTEM"))
{
EXECSQLEXECUTEBEGINDBMS_PIPE.UNPACK_MESSAGE(:return_name);
DBMS_PIPE.UNPACK_MESSAGE(:value);
END;
END-EXEC;
value.arr[value.len]='';
printf("Willexecutesystem command'%s'n", value.arr);/*运行os命令*/status=system(value.arr);
EXECSQLEXECUTEBEGINDBMS_PIPE.PACK_MESSAGE('done');
DBMS_PIPE.PACK_MESSAGE(:status);
:status :=DBMS_PIPE.SEND_MESSAGE(:return_name);
END;
END-EXEC;
IF(status)
{
printf
("Daemon errorwhilerespondingtosystem command.");
printf(" status:%dn", status);
}
}
ELSE{
printf
("Daemon error: invalid command'%s'received.n",
command.arr);
}
}
ELSE{
printf("Daemon errorwhilewaitingforsignal.");
printf(" status=%dn", status);
}
}
EXECSQLCOMMITWORKRELEASE;
exit(0);
}
以上代码起名为daemon.pc,用proc预编译:
proc iname=daemon.pc userid=用户名/密码@服务名 sqlcheck=semantics
得到daemon.c,在用c进行编译,注意在NT上要把orasql8.lib加上,否则编译通过,连接没法通过.
3 在服务器上运行daemon.exe
4 在sqlplus运行测试语句:
SQL>variable rvnumberSQL>execute:rv :=DAEMON.EXECUTE_SYSTEM('ls -la');
PL/SQL 过程已成功完成。
SQL>execute:rv :=DAEMON.EXECUTE_SYSTEM('dir');
PL/SQL 过程已成功完成。
DBMS_PIPE的用法见oracle的文档.
利用oracle执行系统命令,利用oracle存储过程执行操作系统命令(转)相关推荐
- 使用复制存储过程执行解决“事务复制中的表大量更新导致无法及时同步”的问题 (转)...
复制存储过程执行应用于事务复制中,当在发布服务器上执行配置的存储过程时,存储过程导致的数据变更不会做为多步骤事务发送到订阅服务器,而仅仅是把执行存储过程的命令发送到订阅服务器. 比如,如果你为一个10 ...
- oracle exist 10053,Oracle中利用10053事件来分析Oracle是如何做出最终的执行计划
我们都知道Oracle从10g开始SQL语句选择什么样的执行方式,是全表扫描,还是走索引的依据是执行代价.那么我们怎么可以去看执行代价的信息呢?通过10053事件可以Oracle依据的执行代价和如何做 ...
- 解决问题:Oracle存储过程执行成功,但数据没有变化
Oracle存储过程执行成功,但数据没有化 一. 检查执行之后,是否在后面加写一行commit; 二. 检查execute语句在where条件后面,操作的字段是否trim(),否则很有可能执行结 ...
- oracle 更新语句不生效,Oracle存储过程执行update语句不报错不生效问题
转载链接:http://lin49940.iteye.com/blog/466626 今天一个同事写oracle 的存储过程遇到了一个问题, 他在里面update 操作不能完成更新的操作, 但是又不会 ...
- Oracle中通过游标执行带参数的存储过程实现解析CLOB字段内的xml字符串:
摘要:近来之前的项目数据出现了问题,原因是由于之前在设计数据库的时候把时间字段设置成了字符串格式,所以给后期的数据操作带来了很大的麻烦,这里提醒一下各位程序猿,以后在开发项目的时候时间字段一定要是时间 ...
- oracle读写文件--利用utl_file包对磁盘文件的读写操作
oracle读写文件--利用utl_file包对磁盘文件的读写操作 摘要: 用户提出一个需求,即ORACLE中的一个表存储了照片信息,字段类型为BLOB,要求能导出成文件形式. 本想写个C#程序来做, ...
- oracle ebs form视频,ORACLE EBS FORM利用模板开发步骤
<ORACLE EBS FORM利用模板开发步骤>由会员分享,可在线阅读,更多相关<ORACLE EBS FORM利用模板开发步骤(13页珍藏版)>请在人人文库网上搜索. 1. ...
- 执行计划信息Oracle 执行计划总结
新手发帖,很多方面都是刚入门,有错误的地方请大家见谅,欢迎批评指正 1 看查Oracle执行筹划的几种方法 1.1 通过PL/SQL Dev工具 1.直接File->New- ...
- SQL语句执行顺序以及oracle基本查询优化
1.select 列 from 表列表名/视图列表名 where 条件. 2.select 列 from 表列表名/视图列表名 where 条件 group by (列列表) having 条件 3. ...
最新文章
- 使用TestStack.White进行Windows UI的自动化测试 (1) 基础篇
- 如何找到Kafka集群的吞吐量极限?\n
- 使用AndroidStudio编译NDK的方法及错误解决方案
- windows文件服务器双机热备_遇到ZFS文件系统如此棘手的问题,这种办法简单又高效!...
- Win10_MySQL环境搭建以及Navicat的使用全解
- MySQL的ODBC安装错误问题!
- (转)基于MVC4+EasyUI的Web开发框架经验总结(10)--在Web界面上实现数据的导入和导出...
- Atitit 程序设计概论 艾提拉著作 目录 1. 界面ui设计	1 2. 编程语言部分	1 3. 面向对象的程序设计	1 4. 算法章节 数据结构	1 5. 第21章 标准库	2 5.1. 文件i
- python中rgb颜色_python颜色显示
- ArduinoUNO实战-第二十二章-红外遥控实验
- ppt如何替换其他mo ban_有没有一个 PPT 技巧让自己觉得人生都亮了?
- u3d canvas设置
- 学习编程的心得(一)
- java中jdk1.8的hashmap为啥要用尾插法,不用头插入。
- 线性方程组求解——基于MTALAB/Octave,Numpy,Sympy和Maxima
- Spring AOP具象化理解(代理模式)
- MFC架构之CWnd类
- [转知乎]网易云音乐的歌单推荐算法是怎样的?
- Opengl绘制网格模型
- SetWinEventHook 事件钩子