`
doris
  • 浏览: 28747 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
社区版块
存档分类
最新评论

oracle的java存储过程执行系统命令

阅读更多
这两天折腾着做了个用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 楼 xiaoxin 2009-07-13  
很喜欢这篇文章,谢谢共享

相关推荐

    在Oracle数据库中运行操作系统命令

    在Oracle数据库中运行操作系统命令是特定场景下的需求,例如在Oracle 8i版本中,当需要在存储过程中执行操作系统级别的任务时,Oracle Enterprise Manager(OEM)提供的作业设定功能可能无法满足灵活的需求。...

    使用Java编写Oracle存储过程.pdf

    在本文中,作者全立新介绍了使用Java编写Oracle9i存储过程的方法,强调了存储过程的优越性,比如提高运行速度、减少网络负荷、提供可靠的安全机制、方便团队开发以及提升服务用户满意度。 为了编写存储过程,首先...

    Oracle存储过程调用bat批处理脚本程序

    Oracle作为一个强大的关系型数据库管理系统,不仅提供了数据存储和查询的功能,还允许我们通过存储过程来执行更复杂的业务逻辑。本话题将详细探讨如何在Oracle存储过程中调用外部的批处理脚本,如Windows系统的BAT...

    java编写oracle的存储过程,为什么调用System.in阻塞IO时不起作用?还报错?

    这个问题通常涉及到Java的多线程概念、I/O流的处理以及Oracle存储过程的执行机制。下面我们将详细探讨这个问题。 首先,Java中的System.in是一个InputStream对象,它代表程序的标准输入流,通常是键盘输入。当调用...

    oracle 存储过程学习经典

    - **原理**: 通过Java存储过程的方式,使得存储过程可以调用Java类的方法。 - **示例**: 定义一个Java类并注册为存储过程,然后在存储过程中调用该Java方法。 #### 十一、Oracle高效分页存储过程实例 - **实现思路...

    项目里用到用java写oracle的存储过程,做个备份

    本项目中,我们将探讨如何利用Java来编写Oracle存储过程,以实现数据库的备份功能。 首先,Oracle存储过程是一种预编译的SQL和PL/SQL代码集合,可以执行特定任务,如数据处理、业务逻辑等。通过Java调用存储过程,...

    Oracle+PlSql存储过程

    7. 使用Java调用Oracle存储过程分为三种情况:无返回值的过程、有单个返回值的过程和返回列表的过程。 **用Java调用Oracle存储过程总结** 1. 无返回值的存储过程:使用CallableStatement的`execute()`方法执行。 2....

    oracle存储过程(语法实例).pdf

    Oracle 存储过程是数据库管理中的重要组成部分,它允许开发者将复杂的业务逻辑和操作封装成独立的可执行单元,以提高代码复用性和系统效率。本文将深入探讨Oracle存储过程的基础知识、语法以及常见问题。 1. **基础...

    在Oracle8i中使用java编写存储过程.rar

    总之,Oracle8i的Java存储过程功能为开发人员提供了一种强大而灵活的方法来扩展数据库的功能,使得数据库不仅仅是存储数据的地方,还可以执行复杂的业务逻辑。通过学习和掌握这一技术,开发者可以创建出更高效、更...

    Oracle存储过程.pdf

    因为存储过程在首次运行时被预编译和优化,查询优化器会分析并给出存储计划,存储在系统表中。而批处理的SQL语句每次运行时都需要预编译和优化,速度较慢。 3. 减轻网络流量:如果某一操作涉及的SQL语句被组织成...

    oracle存储过程学习经典

    Oracle存储过程是数据库编程中的重要概念,它允许开发者将一组SQL语句、PL/SQL块或Java代码封装在数据库中执行,从而实现复杂的业务逻辑。这种做法可以减少网络通信的次数,提高性能,而且由于代码直接在数据库...

    如何实现Java对Oracle存储过程的调用.pdf

    通过这种方式,可以将复杂的业务逻辑或操作系统级别的任务封装在Oracle存储过程中,然后通过Java程序调用,实现了数据库与操作系统的交互。这种做法在处理大量数据或者需要高效计算的场景下尤其有用,同时还能保持...

    java调用oracle存储过程.docx

    ### Java调用Oracle存储过程详解 #### 一、概述 在企业级应用开发中,数据库存储过程被广泛用于实现复杂的业务逻辑处理。Oracle作为一种流行的数据库管理系统,提供了丰富的特性支持复杂查询与事务处理。结合Java...

    Java调用Oracle存储过程的方法研究.pdf

    在Java编程中,与Oracle数据库进行交互时,有时需要调用存储过程来执行特定的数据库操作。存储过程是一种预编译的SQL代码集合,它可以接受输入参数,执行复杂逻辑,并返回结果。在Oracle数据库中,存储过程有助于...

    java调用shell脚本执行sqlldr与存储过程

    在java代码中调用执行shell脚本,sqlldr导数与使用sqlplus在shell调用执行存储过程。 linux环境中有2个dba的用户:oracle、erm 还有1个web用户:erm 在linux环境中,这三个用户都可以直接在任意目录下执行该shell...

    oracle存储过程学习经典[语法+实例+调用]

    Oracle存储过程是Oracle数据库中一种用于封装SQL语句、PL/SQL语句或Java语句的程序单元,它可以包含一系列操作,使得商业规则和业务逻辑可以从应用程序中独立出来,集中存储在数据库中。存储过程的好处包括代码的...

    Oracle调用Java代码过程

    Oracle调用Java代码过程...然而,它也有一些限制,例如性能可能不如原生的Oracle存储过程,且维护和调试Java代码需要对Java和Oracle都有深入的理解。在实际应用中,需要权衡利弊,根据具体需求来决定是否采用这种方式。

    Oracle_的存储过程及游标

    在Oracle中,存储过程由`CREATE PROCEDURE`语句创建,并可以通过`EXECUTE`命令执行。 1. **函数与存储过程的区别**: - 函数必须有返回值,而过程则不需要。 - 函数可以直接在SQL语句中调用,而过程需要通过`...

    存储过程入门

    存储过程是Oracle数据库中一种非常重要的对象,它是由一系列SQL语句、PL/SQL语句以及Java语句组成的程序模块。通过将商业规则和业务逻辑存储在数据库中,存储过程可以被多个应用程序多次调用,这不仅可以减少数据库...

Global site tag (gtag.js) - Google Analytics