设为首页 收藏本站
查看: 1940|回复: 0

[经验分享] oracle的java存储过程执行系统命令

[复制链接]
YunVN网友  发表于 2016-8-16 06:55:08 |阅读模式
这两天折腾着做了个用oracle的java存储过程执行系统命令的功能,在网上找了很多资料,总算解决了,整理出来,顺便复习一下

需求是: 在数据库中有个job定时执行某任务,其中需要调用操作系统命令生成多个文件夹和文件内容,并把他们打包.
环境是: linux AS3 ,oracle 9.2.0.4
实现过程:
1、 用sysdba用户赋予执行job的数据库用户权限,包括文件操作的权限和执行系统命令的权限,命令为:
SQL> exec dbms_java.grant_permission('USERNAME','SYS:java.io.FilePermission','<<ALL FILE>>','read,write,execute,delete');
SQL> exec dbms_java.grant_permission('USERNAME','SYS:java.lang.RuntimePermission','*','WriteFileDescriptor');
其中,USERNAME是数据库用户名,<<ALL FILE>>指所有文件
2、用执行job的用户登录,并编写java存储过程
java代码
public class RunCmd
{
public static int Run(String args)
{
Runtime rt = Runtime.getRuntime();
String os=System.getProperty("os.name").toLowerCase().trim();

String cmd[]={"/bin/sh","-c",args};
int rc = -1;
try{
   if(rt!=null&&args!=null){
    Process p;
   if(os.startsWith("windows"))  //windows环境下
     p = rt.exec(args);
  else
     p=rt.exec(cmd);  //linux环境下,暂时不考虑其他环境
     if(p!=null){
       int bufSize = 4096;
       BufferedInputStream bis =new BufferedInputStream(p.getInputStream(), bufSize);
       int len;
       byte buffer[] = new byte[bufSize];
       while ((len = bis.read(buffer, 0, bufSize)) != -1)
       System.out.write(buffer, 0, len);
       rc = p.waitFor();
     }else{
        System.out.println("p is null");
     }
   }else{
      System.out.println("rt/args is null");
   }   
  }catch (Exception e)
  {
    e.printStackTrace();
    rc = -1;
  }  
  finally
  {
  System.out.println("rc="+rc);
   return rc;
  }
  }
  }
其中,要注意的是在windows环境和linux环境对命令执行的不同,是因为linux下有重定向的问题。

oracle函数定义
create or replace function RUN_CMD(p_cmd in varchar2) return Number
As
language Java name 'RunCmd.Run(java.lang.String) return integer';

主任务过程
create or replace procedure tartask(pdtask in number,path in varchar2) Is
Cursor cur_code Is
Select code,title From pd_res Where task_id=pdtask;
v_code Varchar2(10);
v_rc Number;
v_file Varchar2(400);
v_cmd Varchar2(4000);
v_str Varchar2(4000);
v_title Varchar2(500);
Begin
--在linux环境下
   --创建任务主目录
   v_cmd:='mkdir '||path||'/'||pdtask;
   v_rc:=run_cmd(v_cmd);
   
   --对每个资源,创建子目录
   Open cur_code;
     Loop
       Begin
       Fetch cur_code Into  v_code,v_title;
       Exit When cur_code%Notfound;
            --code
            v_cmd:= 'mkdir '||path||'/'||pdtask||'/'||v_code;
            v_rc:=run_cmd(v_cmd);
             --meta
            --mkdir meta
            v_cmd:= 'mkdir '||path||'/'||pdtask||'/'||v_code||'/meta';
            v_rc:=run_cmd(v_cmd);
            v_file:=path||'/'||pdtask||'/'||v_code||'/meta/dc.xml';
            -----------------------------------------------------------------------------------------
            --dc.xml
            --echo 123321 > d:\1.txt
           -- v_cmd:='export LANG=utf-8';
           -- v_rc:=run_cmd(v_cmd);
            
            v_str:='<?xml version=\"1.0\" encoding=\"utf-8\"?>';
            v_cmd:=' echo -E "'||v_str||'" > '||v_file;
            v_rc:=run_cmd(v_cmd);
            v_cmd:='echo -E "" >> '||v_file;
            v_rc:=run_cmd(v_cmd);
            
            v_str:='<dublincore xmlns:dc=\"http://purl.org/dc/elements/1.0/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:dcterms=\"http://purl.org/dc/terms/\">';
            v_cmd:= 'echo -E "'||v_str||'" >> '||v_file;
            v_rc:=run_cmd(v_cmd);
             v_cmd:='echo -E "" >> '||v_file;
            v_rc:=run_cmd(v_cmd);
            
            v_str:='<dc:identifier>'||v_code||'</dc:identifier>';
            v_cmd:= 'echo -E "'||v_str||'" >> '||v_file;
            v_rc:=run_cmd(v_cmd);
             v_cmd:='echo -E "" >> '||v_file;
            v_rc:=run_cmd(v_cmd);
            
          --  v_str:='<dc:title>'||'中国 泰山'||'</dc:title>';
            --v_cmd:= 'echo -E "'||v_str||'" >> '||v_file;
           -- v_rc:=run_cmd(v_cmd);
           --  v_cmd:='echo -E "" >> '||v_file;
          --  v_rc:=run_cmd(v_cmd);
            
            v_str:='</dublincore>';
            v_cmd:= 'echo -E "'||v_str||'" >> '||v_file;
            v_rc:=run_cmd(v_cmd);
             v_cmd:='echo -E "" >> '||v_file;
            v_rc:=run_cmd(v_cmd);
       End;
     End Loop;
   Close cur_code;  
   
   --打包创建好的目录
   v_cmd:='tar -zcvf '||path||'/'||pdtask||'.tar.gz'||' '||path||'/'||pdtask;
   v_rc:=run_cmd(v_cmd);
end tartask;
这是在linux环境下的任务代码,windows环境下类似,就是输入的命令稍微有些不同,其中包括了目录创建,文件创建和写文件,注掉部分是因为中文问题解决不了,输入的中文都存成乱码,最后决定这个由人工来录入;

问题和总结
在这次解决过程中,遇到了几个问题
1、windows下和linux下调用系统命令的输入,windows下,命令形式为:cmd /c dir,整个是一个字符串输入,而在linux下,需要用{"/bin/sh","-c","ls"}这样的数组形式输入
2、创建并写文件,用echo xxx > filepath 命令
3、在用echo写文件的过程中,遇到了“>”符不能输入的问题,因为会被误认为是重定向符号>,在windows里,可以用在>前加^符号来解决,在linux下,用命令echo带参数 -E 解决
4、在用echo写文件时,换行,写入新行,在windows下,用 echo. > filepath,就是在echo后直接跟一个.号解决,在linux下,用 echo "" > filepath解决
5、echo的>是创建并写入,因此如果该文件存在,会被覆盖,如果需要在文件末添加数据,用>>代替>
6、就是中文的问题,目前还没有解决掉,把java类放到操作系统里执行写中文是没有问题的,echo进去没问题,但是放到oracle里写就会是乱码,不知道是什么地方需要设置,实在是把我折腾坏了,先放着,以后或许忽然就看到解决方法了

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-258316-1-1.html 上篇帖子: Oracle SQL中IN与EXISTS的比较 下篇帖子: 简单提高ORACLE数据库的查询统计速度
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表