侧边栏壁纸
  • 累计撰写 129 篇文章
  • 累计创建 13 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

【ORACLE】在oracle中执行操作系统命令(二)(linux)

DarkAthena
2021-11-01 / 0 评论 / 0 点赞 / 1030 阅读 / 4149 字

前文【AIO】使用ORACLE存储过程执行windows操作系统命令中用常规分析的思路,针对windows环境的oracle数据库,做了一个通用的操作系统执行过程,在偶然间看到了oracle官方补丁包代码后【ORACLE】有时候看看oracle官方安装包的代码也能有一些百度上找不到的收获(数据库执行linux命令),发现如果活用参数,可以让代码更简洁,下面直接上代码。

create or replace procedure run_linux_sh_text(i_script varchar2) is
/*by DarkAthena 2021-11-01*/
  sched_job_name varchar2(30);
begin
  sched_job_name := dbms_scheduler.generate_job_name(prefix => 'SCRIPT_');
  DBMS_SCHEDULER.create_job(job_name            => sched_job_name,
                            job_type            => 'EXECUTABLE',
                            job_action          => '/bin/sh',
                            number_of_arguments => 2,
                            enabled             => false,
                            auto_drop           => true);
  DBMS_SCHEDULER.set_job_argument_value(sched_job_name, 1, '-c');
  DBMS_SCHEDULER.set_job_argument_value(sched_job_name, 2, i_script);
  DBMS_SCHEDULER.run_job(job_name => sched_job_name);
end;
/

使用时,只需要把要执行的sh脚本的内容作为参数传入过程即可,比如

begin
run_linux_sh_text(q'{#!/bin/bash
mkdir /home/oracle/aaa
exit 0 }');
end;
/

运行后即可看到 "aaa" 目录已经被创建,而且过程中生成的sched_job也没了。

下面开始说明这个过程

sched_job_name := dbms_scheduler.generate_job_name(prefix => 'SCRIPT_');

dbms_scheduler.generate_job_name 这个函数,可以传入前缀字符串,然后使用内部序列拼接成一个唯一的job名称,如果不传参数,则默认为"JOB$_"。使用这个的目的是可以让多个命令并行执行。我之前没注意这个,之前写的版本里为了让多任务并行不冲突,是手动拼接了个随机数。

DBMS_SCHEDULER.create_job(job_name            => sched_job_name,
                            job_type            => 'EXECUTABLE',
                            job_action          => '/bin/sh',
                            number_of_arguments => 2,
                            enabled             => false,
                            auto_drop           => true);

DBMS_SCHEDULER.create_job 这个过程创建一个job,

  • job_name 为 job的名称
  • job_type 为'EXECUTABLE'表示执行操作系统命令,
  • job_action 为要执行的命令,由于我们要执行的命令可能太长,这里只放启动入口 '/bin/sh'
  • number_of_arguments 为参数个数
  • enabled 为是否启用,这里因为我们还要设参数,所以设置成不启用
  • auto_drop 为运行后是否删除此job,因为这个通用的场景是一次性执行,所以设置为自动删除,如果是要调试的话,建议改成不自动删除,因为一旦设置成自动删除,那么不管是成功还是失败都会删掉,当然也可以去日志视图查看运行日志,因为删job不会删日志的。
DBMS_SCHEDULER.set_job_argument_value(sched_job_name, 1, '-c');
DBMS_SCHEDULER.set_job_argument_value(sched_job_name, 2, i_script);

DBMS_SCHEDULER.set_job_argument_value 为设置job参数,它本身的三个参数分别为job名称,参数位置,参数内容,这里分别设置2个job参数,第一个参数 "-c" 是把后面的整个字串当成一条命令执行,第二个参数就是我们传入的要执行的sh内容。

DBMS_SCHEDULER.run_job(job_name => sched_job_name);
end;

最后运行此job,完。

我把这个整理出来后,没想到这个方式竟然比网上流传的java版本更简单,而且不像java那样还要进行复杂的授权。而且重点是,不再需要先在操作系统生成sh文件再去执行,而是在数据库中就提前准备好了所有指令,直接往操作系统发送即可。

windows版本优化进行中...

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin
博主关闭了所有页面的评论