oracle定时任务(dbms_job、dbms_scheduler)

淡淡的烟草味﹌ 2021-08-19 15:18 750阅读 0赞

本篇主要讲讲oracle的定时任务。

刚准备说说DBMS_JOB包就看到已经被DBMS_SCHEDULER 取代了(oracle10g以后)。不管,我们先说说DBMS_JOB包。

  1. The DBMS_JOB package has been superseded by the DBMS_SCHEDULER package. In particular, if you are administering jobs to manage system load, you should consider disabling DBMS_JOB by revoking the package execution privilege for users.

说到定时任务,我们先说说它怎么用吧。

DBMS_JOB创建定时任务:

  1. DBMS_JOB.SUBMIT(
  2. job OUT BINARY_INTEGER, --任务ID
  3. what IN VARCHAR2, --这个任务要执行什么,可以是存储过程,别忘了分号 'ProcedureName;'
  4. NEXT_DATE IN DATE DEFAULT SYSDATE, --下次执行时间
  5. interval IN VARCHAR2 DEFAULT 'NULL', --执行频率,默认'null',只执行一次
  6. no_parse IN BOOLEAN DEFAULT FALSE, --创建时是否不需要解析与其关联的sql,如存储过程,默认false,是会解析的
  7. instance IN BINARY_INTEGER DEFAULT ANY_INSTANCE,--可以执行该任务的实例,默认any
  8. force IN BOOLEAN DEFAULT FALSE); --暂时就按强制执行理解

实例:

  1. declare
  2. job number;
  3. begin
  4. sys.DBMS_JOB.SUBMIT(JOB => job, WHAT => 'P_TB_SBF_DDMX;', --注意有分号 'P_TB_SBF_DDMX'是存储过程名称
  5. NEXT_DATE => TRUNC(SYSDATE + 1) + 1 / 24,
  6. INTERVAL => 'TRUNC(SYSDATE + 1) + 1 / 24');
  7. commit ;
  8. END;
  9. /

简单介绍下dbms_job包下常见的过程(执行每个操作之后,都要commit;):

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') 修改定时任务的执行时间

创建完定时任务之后,可通过查看:

  1. select * from DBA_JOBS;

DBMS_JOB辨析:

1、细心的你会发现,创建job的方法参数NEXT_DATE是不带引号的,而INTERVAL 是带引号的。

20191225171607817.png

因为它们的类型是不一样的。一个是Date,一个是varchar2。

2、来说说INTERVAL的表达式。

正因为NEXT_DATE和INTERVAL的类型区别,我大胆地猜测:

系统会每隔一定时间扫描定时任务队列,但时间等于NEXT_DATE时就执行该任务(加入任务执行队列),同时根据INTERVAL表达式计算出下一次执行的事件,存入NEXT_DATE中。

这样就好理解了。

拿出官方文档中的例子,看来我是对的:

  • If the job completes successfully, then this new date is placed in next_date. interval is evaluated by plugging it into the statement select interval into next_date from dual;
  • The interval parameter must evaluate to a time in the future. Legal intervals include:






















    Interval Description
    ‘sysdate + 7’ Run once a week.
    ‘next_day(sysdate,’’TUESDAY’’)’ Run once every Tuesday.
    ‘null’ Run only once.

就是在执行的时候根据INTERVAL计算出下一次的执行时刻,可知'sysdate + 7'就是在往后加7天,就是一周一次。'next_day(sysdate,''TUESDAY'')'就是取下一个星期四,即每个星期四。

next_day(date,char)函数返回的是下一周的weekday,其中char是星期英文的全称或简称,另外时分秒是参照date的时分秒的)参见:https://docs.oracle.com/cd/E11882_01/server.112/e41084/functions106.htm#SQLRF00672

另外,上面例子中的’TRUNC(SYSDATE + 1) + 1 / 24’,trunc()函数是用来round和截取日期用的,如

  1. select trunc(sysdate,'mi') from dual; --精确到分,忽略秒

20191225174335521.png

  1. select trunc(sysdate,'HH') from dual; --精确到时,忽略分秒

20191225174432637.png

另外,试了一下,下面这两个结果是一样的,都是精确到天

  1. select trunc(sysdate) from dual --精确到天,忽略时分秒
  2. union all
  3. select trunc(sysdate, 'DD') from dual; --精确到天,忽略时分秒

20191225174816723.png

所以’TRUNC(SYSDATE + 1) + 1 / 24’就是取下一天的24分之1天,也就是1小时。就是下一天的凌晨一点。

测试一下吧:

  1. select trunc(sysdate + 2) + 3 / (24) + 30 / (24 * 60) + 30 / (24 * 60 * 60) from dual;

这是每隔一天,在凌晨3:30:30执行。

参看https://docs.oracle.com/cd/E11882_01/server.112/e41084/functions255.htm#SQLRF52058

也看一下dbms_scheduler

https://blog.csdn.net/WuLex/article/details/81868916

发表评论

表情:
评论列表 (有 0 条评论,750人围观)

还没有评论,来说两句吧...

相关阅读