oracle定时任务(dbms_job、dbms_scheduler)
本篇主要讲讲oracle的定时任务。
刚准备说说DBMS_JOB包就看到已经被DBMS_SCHEDULER 取代了(oracle10g以后)。不管,我们先说说DBMS_JOB包。
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创建定时任务:
DBMS_JOB.SUBMIT(
job OUT BINARY_INTEGER, --任务ID
what IN VARCHAR2, --这个任务要执行什么,可以是存储过程,别忘了分号 'ProcedureName;'
NEXT_DATE IN DATE DEFAULT SYSDATE, --下次执行时间
interval IN VARCHAR2 DEFAULT 'NULL', --执行频率,默认'null',只执行一次
no_parse IN BOOLEAN DEFAULT FALSE, --创建时是否不需要解析与其关联的sql,如存储过程,默认false,是会解析的
instance IN BINARY_INTEGER DEFAULT ANY_INSTANCE,--可以执行该任务的实例,默认any
force IN BOOLEAN DEFAULT FALSE); --暂时就按强制执行理解
实例:
declare
job number;
begin
sys.DBMS_JOB.SUBMIT(JOB => job, WHAT => 'P_TB_SBF_DDMX;', --注意有分号 'P_TB_SBF_DDMX'是存储过程名称
NEXT_DATE => TRUNC(SYSDATE + 1) + 1 / 24,
INTERVAL => 'TRUNC(SYSDATE + 1) + 1 / 24');
commit ;
END;
/
简单介绍下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')
修改定时任务的执行时间
创建完定时任务之后,可通过查看:
select * from DBA_JOBS;
DBMS_JOB辨析:
1、细心的你会发现,创建job的方法参数NEXT_DATE是不带引号的,而INTERVAL 是带引号的。
因为它们的类型是不一样的。一个是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 selectinterval
intonext_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和截取日期用的,如
select trunc(sysdate,'mi') from dual; --精确到分,忽略秒
select trunc(sysdate,'HH') from dual; --精确到时,忽略分秒
另外,试了一下,下面这两个结果是一样的,都是精确到天
select trunc(sysdate) from dual --精确到天,忽略时分秒
union all
select trunc(sysdate, 'DD') from dual; --精确到天,忽略时分秒
所以’TRUNC(SYSDATE + 1) + 1 / 24’就是取下一天的24分之1天,也就是1小时。就是下一天的凌晨一点。
测试一下吧:
select trunc(sysdate + 2) + 3 / (24) + 30 / (24 * 60) + 30 / (24 * 60 * 60) from dual;
这是每隔一天,在凌晨330执行。
参看https://docs.oracle.com/cd/E11882_01/server.112/e41084/functions255.htm#SQLRF52058
也看一下dbms_scheduler
https://blog.csdn.net/WuLex/article/details/81868916
还没有评论,来说两句吧...