oracle在创建和管理job主要借助两个包,分别为DBMS_JOB和DBMS_SCHEDULER,下面就针对这两个包如何管理job进行阐述:
dbms_job是一个PL/SQL包,用来调度job,已经被oracle的Scheduler所替代,首先我们做一个例子:
1、创建一个测试表test;
create table test(ttime date,detail varchar2(20));
2、创建一个存储过程test_proc,使得每次执行该存储过程的时候向表中插值;
create or replace procedure test_proc as
begin
insert into test values(sysdate,'测试');
end;
/
3、创建一个job,每天的凌晨去运行一下上面的存储过程;
declare test_job number;
begin
dbms_job.submit(test_job,'test_proc;',sysdate,'trunc(sysdate) + 1 + 1/24');
commit;
end;
/
4、运行一下此job;
begin
dbms_job.run(6);
end;
/
注:其中的 dbms_job.run(6);中的6是根据test_job的值不同也不同,job参数(test_job)是由Submit()过程返回的binary_ineger。这个值用来唯一标识一个工作;
下面对创建job中的几个参数进行说明:
DBMS_JOB.SUBMIT (
job OUT BINARY_INTEGER, --job参数的名称(上例的test_job)
what IN VARCHAR2, --执行的存储过程
next_date IN DATE DEFAULT sysdate, --何时运行这个job
interval IN VARCHAR2 DEFAULT 'null', --何时这个job被从新执行
no_parse IN BOOLEAN DEFAULT FALSE, --是否从新解析
instance IN BINARY_INTEGER DEFAULT any_instance, --指定哪个实例去执行(用在RAC环境下)
force IN BOOLEAN DEFAULT FALSE --是否必须由执行的实例才能执行
);
其中的interval的设置是一个难点,在此阐述几个常用的设置值:
1、 每分钟执行
Interval => TRUNC(sysdate,’mi’) + 1 / (24*60)
2、 每天定时执行
例如:每天的凌晨2点执行
Interval => TRUNC(sysdate) + 1 +2 / (24)
3、 每周定时执行
例如:每周一凌晨2点执行
Interval => TRUNC(next_day(sysdate,'星期一'))+2/24
4、 每月定时执行
例如:每月1日凌晨2点执行
Interval =>TRUNC(LAST_DAY(SYSDATE))+1+2/24
5、 每季度定时执行
例如每季度的第一天凌晨2点执行
Interval => TRUNC(ADD_MONTHS(SYSDATE,3),'Q') + 2/24
6、 每半年定时执行
例如:每年7月1日和1月1日凌晨2点
Interval => ADD_MONTHS(trunc(sysdate,'yyyy'),6)+2/24
7、 每年定时执行
例如:每年1月1日凌晨2点执行
Interval =>ADD_MONTHS(trunc(sysdate,'yyyy'),6)+2/24
下面我们介绍几个相关的job操作:
删除job:dbms_job.remove(jobno);
修改要执行的操作:job:dbms_job.what(jobno,what);
修改下次执行时间:dbms_job.next_date(job,next_date);
修改间隔时间:dbms_job.interval(job,interval);
停止job:dbms_job.broken(:job1,broken,nextdate);
启动job:dbms_job.run(jobno);
暂停job: Broken()暂停job;
如何去查看job的运行情况,使用两个视图user_jobs和dba_jobs;
需要注意的问题:
1)job的下一次执行时间的确定:一个job必须run一次之后,才能按照设定的间隔确定下次运行的时间。
2)如果job运行时间小于两次的间隔,则下次运行时间等于job开始运行时间+间隔时间;如果job运行时间大于等于两次的间隔,则下次运行时间等于上次job运行结束的
时间。