天天看点

Oracle JOB两种作业建立及比较

存储过程准备 

create table job_test (a date);

create or replace procedure test123 as

begin

    insert into JOB_TEST values(sysdate);

    commit;

end;

第一种,使用dbms_job存储过程建立作业

variable aaa number

begin

 dbms_job.submit(:aaa,'test123;',sysdate,'sysdate+1/1440',true);

end;

/

begin

 dbms_job.run(:aaa);

end;

/

此处注意,执行job必须在其所属用户下执行,否则会报该jobid不存在。

begin

 dbms_job.remove(:aaa);

end;

数据字典

select * from dba_jobs;

第二种 使用schedule_job建立作业

begin

  dbms_scheduler.create_job(job_name        => 'testjob',

                            job_type        => 'stored_procedure',

                            job_action      => 'person.test123',

                            start_date      => to_date('201708251001','yyyymmddhh24mi'),

                            repeat_interval => 'freq=minutely;interval=1');

end;

/

begin

 dbms_scheduler.enable('testjob');

end;

begin

 dbms_scheduler.run_job('testjob');

end;

?????此处注意,执行job必须在其所属用户下执行,否则会报该jobid不存在。

begin

 dbms_scheduler.drop_job('testjob');

end;

/

数据字典:

select *from dba_scheduler_job_log where job_name='TESTJOB';

select *from dba_scheduler_jobs where job_name='TESTJOB';

注意:建立job的时候请注意数据库的参数job_queue_processes参数不能是0,如果是0的话数据库进程无法启动。修改参数后需重启

ps -ef | grep ora_j | grep -v grep 可通过此命令查看和job相关的调度进程是否启动,如果未启动则job一定不会执行。

job执行的由于执行需要依赖上一次执行,因此start_date最好设置为当前时间向后一点点,或者用固定时间来代替

比较:dbms_job和schedule_job的优劣,dbms_job没有job执行日志,schedule_job有日志,因此建议使用shcedule_job

dbms_job 时间间隔设置interval设置:

每天午夜12点: 'TRUNC(SYSDATE + 1)'

每天早上8点30分: 'TRUNC(SYSDATE + 1) + (8*60+30)/(24*60)'

每星期二中午12点: 'NEXT_DAY(TRUNC(SYSDATE ), ''TUESDAY'' ) + 12/24'

每个月第一天的午夜12点: 'TRUNC(LAST_DAY(SYSDATE ) + 1)'

每个季度最后一天的晚上11点: 'TRUNC(ADD_MONTHS(SYSDATE + 2/24, 3 ), 'Q' ) -1/24'

每星期六和日早上6点10分: 'TRUNC(LEAST(NEXT_DAY(SYSDATE, ''SATURDAY"), NEXT_DAY(SYSDATE, "SUNDAY"))) + (6×60+10)/(24×60)'

每月25号00:00执行: 'TRUNC(LAST_DAY(SYSDATE ) + 25)'

--------------------------

1:每分钟执行

Interval => TRUNC(sysdate,'mi') + 1/ (24*60)

Interval => sysdate+1/1440

2:每天定时执行

例如:每天的凌晨1点执行

Interval => TRUNC(sysdate) + 1 +1/ (24)

3:每周定时执行

例如:每周一凌晨1点执行

Interval => TRUNC(next_day(sysdate,'星期一'))+1/24

4:每月定时执行

例如:每月1日凌晨1点执行

Interval =>TRUNC(LAST_DAY(SYSDATE))+1+1/24

5:每季度定时执行

例如每季度的第一天凌晨1点执行

Interval => TRUNC(ADD_MONTHS(SYSDATE,3),'Q') + 1/24

6:每半年定时执行

例如:每年7月1日和1月1日凌晨1点

Interval => ADD_MONTHS(trunc(sysdate,'yyyy'),6)+1/24

7:每年定时执行

例如:每年1月1日凌晨1点执行

Interval =>ADD_MONTHS(trunc(sysdate,'yyyy'),12)+1/24

schedule_job时间间隔interval设置:

例如:设置任务仅在周5的时候运行:  

REPEAT_INTERVAL => 'FREQ=DAILY; BYDAY=FRI';  

REPEAT_INTERVAL => 'FREQ=WEEKLY; BYDAY=FRI';  

REPEAT_INTERVAL => 'FREQ=YEARLY; BYDAY=FRI';   

  上述三条语句虽然指定的关键字小有差异,不过功能相同。  

  设置任务隔一周运行一次,并且仅在周5运行:  

REPEAT_INTERVAL => 'FREQ=WEEKLY; INTERVAL=2; BYDAY=FRI';   

  设置任务在当月最后一天运行:  

REPEAT_INTERVAL => 'FREQ=MONTHLY; BYMONTHDAY=-1';   

  设置任务在3月10日运行:  

REPEAT_INTERVAL => 'FREQ=YEARLY; BYMONTH=MAR; BYMONTHDAY=10'; REPEAT_INTERVAL => 'FREQ=YEARLY; BYDATE=0310';   

  上述两条语句功能相同。  

  设置任务每10隔天运行:  

REPEAT_INTERVAL => 'FREQ=DAILY; INTERVAL=10';   

  设置任务在每天的下午4、5、6点时运行:  

REPEAT_INTERVAL => 'FREQ=DAILY; BYHOUR=16,17,18';   

  设置任务在每月29日运行:  

REPEAT_INTERVAL => 'FREQ=MONTHLY; BYMONTHDAY=29';   

  设置任务在每年的最后一个周5运行:  

REPEAT_INTERVAL => 'FREQ=YEARLY; BYDAY=-1FRI';   

  设置任务每隔50个小时运行:  

REPEAT_INTERVAL => 'FREQ=HOURLY; INTERVAL=50';   

  另外,你是否在怀念常规job中设置interval的简便,虽然功能较弱,但是设置操作非常简单,无须懊恼,其实SCHEDULER中的REPEAT_INTERVAL也完全可以按照那种方式设置,前面都说了,REPEAT_INTERVAL实际上是指定周期,直接指定一个时间值,当然也是周期喽。   

或者也可以类似dbms_job写法:

REPEAT_INTERVAL => 'trunc(sysdate)+1'   

  又比如设置任务每周执行一次:  

REPEAT_INTERVAL => 'trunc(sysdate)+7'