oracle使用DBMS_SCHEDULER调度作业

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;
    /

其中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'

另外使用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;
    /

调度现在可以支持调用外部程序了,这点很强大。
目前程序支持三种类型:
- 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  /

调度的相关操作

作业相关操作

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

exec dbms_scheduler.run_job(¨time_synchron¨);

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

exec dbms_scheduler.stop_job(¨time_synchron¨);

查看作业相关情况

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

你可能感兴趣的:(oracle)