Oracle 定时任务 作业调度计划 DBMS_JOB DBMS_SCHEDULE使用方法

版权声明:本文为博主原创文章,转载请申明原文出处。 https://blog.csdn.net/xuheng8600/article/details/84861173

oracle定时任务dbms_job与dbms_scheduler使用方法

2018年08月20日 13:18:20 风灵使 阅读数:111

工作中需要一个定时任务来抽取数据,之前采用的是dbms_job包下的过程来创建job,遇到了一些问题。找了下资料,得知oracle10g以后就推荐采用dbms_scheduler包来取代dbms_job来创建定时任务。下面简单介绍下两者的使用方法及使用过程中的一些体会。

1.先创建日志表,用于记录存储过程执行时间及结果

    create table bak_job_test(date_time date,mark varchar2(200));
  • 1

2.创建一个存储过程,用于创建表

     create or replace procedure my_test authid current_user is
       v_count number := 0;
       v_mess varchar2(200) := '';
     begin
      select count(1) into v_count from user_tables t where t.TABLE_NAME = 'BAK_JOB_TABLES';
       if  v_count > 0 then
          execute immediate 'drop table bak_job_tables purge';
       end if;
      execute immediate 'create table bak_job_tables as select * from user_tables where 1=2';
      insert into bak_job_test(date_time,mark) values(sysdate,'success');
exception
when others then
v_mess := substr(SQLERRM,0,200);
insert into bak_job_test(date_time,mark) values(sysdate,v_mess);
      end;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

3.使用dbms_job包创建定时任务

      declare
          myjob number; 
       begin 
dbms_job.submit(myjob,'begin my_test; end;',sysdate,'TRUNC(sysdate,''mi'') + 1 / (24*60)');
commit;
        end;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

定时器1分钟执行一次,调用存储过程创建表,结果报错:权限不足。之前了解过,定义存储过程时加上authid current_user就可以在存储过程里面使用当前用户所角色的权限,出现这种问题 让人很费解,手动授权grant create table to user之后,确实可以解决这个问题,但是这种方式不通用,特别是存储过程里面用到其他的权限的时候就不方便了。所以决定试试dbms_scheduler包来创建定时任务。

先简单介绍下dbms_job包下常见的过程:

1) dbms_job.remove(jobId) 删除job定时任务,可以从user_jobs视图中查看job的详细情况

2) dbms_job.run(jobid) 运行定时任务

3) dbms_job.broken(jobid,true) 终止定时任务

4) dbms_job.interval(jobid,'interval') 修改定时任务的执行时间

4.使用dbms_scheduler创建定时任务

使用dbms_scheduler需要具有create job权限,对定时任务一些操作需要具有MANAGE SCHEDULER权限,如:dbms_scheduler.stop_job('my_job_test',true);

     BEGIN
     dbms_scheduler.create_job(job_name        => 'my_job_test',
                             job_type        => 'STORED_PROCEDURE',
                             job_action      => 'my_test',
                              start_date      => sysdate,
                             repeat_interval => 'sysdate + 1/1440',
                             enabled         => TRUE,
                             comments        => 'test');
     end;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

定时器执行,调用存储过程创建表成功了,不需要显示的授权grant create table to user,只需要存错过程定义为authid current_user即可。个人觉得dbms_job在调用authid current_user的存储过程的时候,未能调用到用户具有的角色的权限,这或许是dbms_job的一个bug

简单介绍下dbms_scheduler关于定时任务的一些常用过程:

1) dbms_scheduler.run(jobName) 运行job

2) dbms_scheduler.stop_job(jobName,force) 停止jobforce默认为falseoracle建议false停止失败情况下,使用true,且使用true需要有manage scheduler权限

3) dbms_scheduler.drop_job(jobName) 删除job

4) dbms_scheduler.enable(jobName) 打开job

5) dbms_scheduler.disable(jobName,force) 禁用jobforce参数用于dependencies,如果TRUE,即使其他对象依赖于它,操作也能成功

相关视图

1) user_scheduler_jobs 查看job信息

2) User_Scheduler_Job_Log job job日志

3) user_scheduler_job_run_details job运行日志

4) user_scheduler_running_jobs 正在运行的job

总结:

oracle定时任务,dbms_job调用存储过程创建表,需要显示授权,存储过程定义为authid current_user也不行,而dbms_scheduler是不需要显示授权的,这点来说后者更方便使用。另外,dbms_scheduler提供了job运行日志记录视图,可以查看具体的运行日志,比较实用。而且,oracle10g以后也推荐使用dbms_scheduler

https://blog.csdn.net/lldustc_blog/article/details/52944927

Oracle Job 定时调用存储过程

2011年11月03日 13:22:32 webajax 阅读数:702

--创建测试表名
create table job_table(run_date date);
--创建存储过程
create or replace procedure job_proc as
begin
     insert into job_table (run_date) values (sysdate);
end;

--创建job并指定一分钟执行一次
declare
       job number;
begin
     dbms_job.submit(job,'job_proc;',sysdate,'TRUNC(sysdate,''mi'')+1/(24*60)');
end;

commit;

--暂停任务

--select job from user_jobs 
找出job的id值,然后使用下面的放语句停止任务。

begin
dbms_job.broken(584,true);
end;

--重启任务

begin
dbms_job.run(584);
end;

--删除任务
delete user_jobs where job=584;
drop procedure job_proc;
drop table job_table;

创建job后。系统即会在指定时间里自动调用该存储过程。

关于时间间隔的相关知识:

1.TRUNC(for dates)  

TRUNC函数为指定元素而截去的日期值。  

其具体的语法格式如下:  

TRUNC(date[,fmt])  

其中:  date 一个日期值  fmt 日期格式,该日期将由指定的元素格式所截去。忽略它则由最近的日期截去  

下面是该函数的使用情况:  

TRUNC(TO_DATE('24-Nov-1999 08:00 pm'),'dd-mon-yyyy hh:mi am')  ='24-Nov-1999 12:00:00 am'  

TRUNC(TO_DATE('24-Nov-1999 08:37 pm','dd-mon-yyyy hh:mi am'),'hh') ='24-Nov-1999 08:00:00 am'  

trunc(sysdate,'yyyy') --返回当年第一天.  

trunc(sysdate,'mm') --返回当月第一天.  

trunc(sysdate,'d') --返回当前星期的第一天.  

trunc(sysdate,'dd')--返回当前年月日

trunc函数后面加的数字的单位是天。  

每天凌晨0点0分:trunc(sysdate+1)

每天早上8点 trunc(sysdate+1)+1/3

每天早上8点30分 trunc(sysdate+1)+(8.5*60)/(24*60)

每天早上8点30分 trunc(sysdate+1)+8.5/24

每天早上8点30分 trunc(sysdate+1)+(8*60+30)/(24*60)

https://blog.csdn.net/webajax/article/details/6931770

oracle使用DBMS_SCHEDULER调度作业

置顶 2016年10月27日 13:24:14 lldustc 阅读数:9522 标签: oracle 更多

个人分类: oracle

dbms_scheduler包的功能比dbms_job包强大很多,但是很多初学者直接被它的复杂性吓跑了,跟着我,只需几分钟就会用了。

三个概念

大多数人看到这个包里的函数和函数里众多的参数,就开始晕菜了,不要被这些表象迷惑了,其实这些东西都是围绕着三个基本概念,schedule,program和job。oracle是为了复用的目的,提炼出了调度的这三个要素,弄懂这三个要素,立刻豁然开朗。

schedule

schedule表示调度计划表。调度从什么时间开始被调度,什么时候结束,以什么频度调度。使用DBMS_SCHEDULER.CREATE_SCHEDULE过程创建schedule。

 begin
    DBMS_SCHEDULER.CREATE_SCHEDULE (
      schedule_name     => ¨daily_schedule¨,
      start_date        => SYSDATE,
      repeat_interval   => ¨FREQ=DAILY ; INTERVAL=1¨,
      comments          => ¨every one day¨);
    END;
    /
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

其中repeat_interval参数,支持两种格式: 
- dbms_job里的interval格式,建议让这种晦涩语法见鬼去吧 
- 日历表达式(linux系统的crontab使用的格式)

日历表达式分为三部分: 第一部分是频率,也就是”FREQ”这个关键字,它是必须指定的; 第二部分是时间间隔,也就是”INTERVAL”这个关键字,取值范围是1-999. 它是可选的参数; 第三部分是附加的参数,可用于精确地指定日期和时间,它也是可选的参数,下面这些值都是合法的: 
BYMONTH,BYWEEKNO,BYYEARDAY,BYMONTHDAY,BYDAY 
BYHOUR,BYMINUTE,BYSECOND

看几个例子就会用了

每隔2小时运行一次
repeat_interval => 'FREQ=HOURLY; INTERVAL=2'

每天运行一次
repeat_interval => 'FREQ=DAILY'

每周的1,3,5运行
repeat_interval => 'FREQ=WEEKLY; BYDAY=MON,WED,FRI"

每年的3,6,9,12月的18号运行
repeat_interval => 'FREQ=YEARLY; BYMONTH=MAR,JUN,SEP,DEC; BYMONTHDAY=18'
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

另外使用dbms_scheduler.evaluate_calendar_string可以方便的计算出什么时候执行该调度。

program

program表示调度应该做什么事情,是对程序的抽象。使用DBMS_SCHEDULER.CREATE_PROGRAM创建program

 BEGIN
    DBMS_SCHEDULER.CREATE_PROGRAM (
       program_name           => ¨time_synchronization¨,
       program_action         => ¨/sbin/ntpdate 128.59.67.100¨,
       program_type           => ¨EXECUTABLE¨,
       enabled                => TRUE);
 END;
    /
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

调度现在可以支持调用外部程序了,这点很强大。 
目前程序支持三种类型: 
- PL/SQL块: PLSQL_BLOCK, 
- 存储过程: STORED_PROCEDURE 
- 外部程序: EXECUTABLE, 外部程序可以是一个shell脚本,也可以是操作系统级别的命令。

program_action: 根据program_type的不同,program_action有不同的含义。 
- program_type是存储过程,就需要指定存储过程的名字; 
- program_type是PL/SQL块,就需要输入完整的PL/SQL代码; 
- program_type是外部程序,就需要输入script的名称或者操作系统的指令名

job

job表示按照指定的schedule,执行指定program,完成用户指定的工作。使用DBMS_SCHEDULER.CREATE_JOB创建job。

SQL> BEGIN
  2  DBMS_SCHEDULER.CREATE_JOB (
  3     job_name           =>  ¨time_synchron¨,
  4     program_name       =>  ¨time_synchronization¨,
  5     schedule_name      =>  ¨daily_schedule¨,
  6     enabled            =>  true);
  7  END;
  8  /
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

调度的相关操作

作业相关操作

一般情况下是如果你设定了job的enable是true的话,oracle会按照你的计划,定时调用你的job,不需要手动执行。如果临时需要马上调度job也是可以的。

exec dbms_scheduler.run_job(¨time_synchron¨);
  • 1

如果觉得没有必要继续执行这个job了,可以停止该job,让oracle以后不要再继续调度了。

exec dbms_scheduler.stop_job(¨time_synchron¨);
  • 1

查看作业相关情况

Job 每执行一次,无论成功或失败,均会[DBA|ALL|USER]_SCHEDULER_JOB_LOG中生成一条对应的记录(前提是LOGGING_LEVEL属性值未设置为DBMS_SCHEDULER.LOGGING_OFF),job的详细信息可以通过 
[DBA|ALL|USER]_SCHEDULER_JOB_RUN_DETAILS视图查看。

https://blog.csdn.net/lldustc_blog/article/details/52944927

猜你喜欢

转载自blog.csdn.net/xuheng8600/article/details/84861173
今日推荐