首先,先了解interval的定义
引用
interval VARCHAR2(200) NOT NULL A date function, evaluated at the start of execution, becomes next NEXT_DATE
即在job开始执行时根据date function估算job下次执行的时间(NEXT_DATE)。
通常,我们采用两种方式来设置job的interval:
1. 由date function估算出的时间是固定的
2. 由date function估算出的时间是非固定的
何为固定?何为非固定?
比如说trunc(SYSDATE)+635/1440,trunc(sysdate,'hh')+1/48估算出的时间就是固定的,它不跟随sysdate的变化而变化。而sysdate+1,sysdate+2估算出的时间就是非固定的,因为sysdate变化,sysdate+1和sysdate+2也会跟随变化。
在此,重点阐述的是当interval的值是固定时间时应当注意的事项。如果interval设置的不得当,很可能会出现ORA-12012与ORA-12005错误。为什么会出现这两个错误呢?先模拟出现这两个错误的例子:
创建测试的table、procedure
SQL>
SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
Session altered.
SQL> create table t(dtime date);
Table created.
SQL>
SQL>
SQL> create or replace procedure proc_time
2 as
3 begin
4 insert into t values(sysdate);
5 commit;
6 dbms_lock.sleep(120);
7 end;
8 /
Procedure created.
SQL>
定义job
SQL> DECLARE
1 jobno number;
2 BEGIN
3 sys.DBMS_job.SUBMIT
4 (job => jobno ,
5 what => 'proc_time;',
6 next_date => sysdate,
7 interval => 'trunc(SYSDATE)+666/1440');
8 commit;
9 END;
10 /
PL/SQL procedure successfully completed.
SQL>
job执行完成后,查询插入t表的时间
SQL> select * from t;
DTIME
-------------------
2013-08-24 11:05:26
SQL>
SQL>
SQL> select last_date,what from dba_jobs where job = 21;
LAST_DATE WHAT
------------------- ----------------------------------------
2013-08-24 11:05:26 proc_time;
SQL>
查询interval,可知interval的值是个固定值
SQL> select trunc(SYSDATE)+666/1440 time from dual;
TIME
-------------------
2013-08-24 11:06:00
SQL>
可以知道,job开始执行的时间是2013-08-24 11:05:26(从t表记录的值和dba_jobs视图可以看出)。而job真正完成的时间是2013-08-24 11:05:26 + 120秒,即2013-08-24 11:07:26。
「随着job的结束,视图dba_jobs.interval的值要更新为dba_jobs.next_date的值」。即dba_jobs.next_date='2013-08-24 11:06:00'。可是,此时的sysdate已经大于'2013-08-24 11:06:00',Oracle更新next_date的值并非我们刚开始设置的interval的值,而是比当前sysdate大的值。随即在告警日志文件中抛出ORA-12012和ORA-12005错误。
引用
Sat Aug 24 11:07:31 2013
Errors in file /u01/app/oracle/admin/lonion/bdump/lonion_j000_18414.trc:
ORA-12012: error on auto execute of job 21
ORA-12005: may not schedule automatic refresh for times in the past
为什么会抛出这两个错误呢?因为job执行的时间 > (interval的值-job开始执行的时间),等job执行完后再去更新next_date时,已经过了11:06:00,自然就报错了。
要想避免这个错误,有3种可行的办法:
- 缩短job执行的时间,即优化相关的SQL、逻辑
- 加大interval的值
- 采用非固定的interval
文章推荐阅读
-
关于JOB的两个小问题
-
Oracle Job ORA-12012&ORA-12005 错误的解决
已有 0 人发表留言,猛击->> 这里<<-参与讨论
ITeye推荐