注册 | 登录
欢迎注册会员

当前位置:首页 > 数据库 > ORACLE数据库 > 正文

Oracle作业(JOB)更新next_date的探讨

来源:程序人生 【 】 浏览:358 添加日期:2010-05-27 21:58:04 我要评论(0)

Oracle作业(JOB)更新next_date的探讨


 


本文作者:kamus(kamus@itpub.net)


 


摘要:本文通过实验和事件跟踪来分析Oracle Job执行过程中修改下次执行时间的机制。


 


有些人问,OracleJOB在设定完next_dateinterval之后,到底是什么时候决定下一次运行时间的。可以归纳成以下几个问题。


1 假设我们的JOB设定第一次运行的时间是12:00,运行的间隔是1小时,JOB运行需要耗时30分钟,那么第二次运行是在13:00还是13:30


2 如果是在13:00那是不是说明只要JOB一开始运行,next_date就被重新计算了?


3 JOB的下一次运行会受到上一次运行时间的影响吗?如果受到影响,如何可以避免这个影响而让JOB在每天的指定时刻运行?


 


本文通过一些实验和跟踪来解释上面的所有问题。


 


首先我们选择一个测试用户,假设该用户名为kamus


由于我们在实验用的存储过程中会用到dbms_lock包,所以需要由sys用户先授予kamus用户使用dbms_lock包的权限。


 


d:\Temp>sqlplus "/ as sysdba"


 


SQL*Plus: Release 9.2.0.5.0 - Production on 星期三 12 1 23:56:32 2004


 


Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.


 


 


连接到:


Oracle9i Enterprise Edition Release 9.2.0.5.0 - Production


With the Partitioning, OLAP and Oracle Data Mining options


JServer Release 9.2.0.5.0 - Production


 


SQL> grant execute on dbms_lock to kamus;


 


授权成功。


 


然后用kamus用户登录数据库,创建我们测试使用的存储过程sp_test_next_date


 


create or replace procedure sp_test_next_date as
  p_jobno    number;
  P_nextdate date;
begin
  --
将调用此存储过程的jobnext_date设置为30分钟以后
  select job into p_jobno from user_jobs where what = 'sp_test_next_date;';
  execute immediate 'begin dbms_job.next_date(' || to_char(p_jobno) || ',sysdate+1/48);commit;end;';
  --
修改完毕以后检查user_jobs视图,输出job目前的next_date
  select next_date
    into P_nextdate
    from user_jobs
   where what = 'sp_test_next_date;';
  dbms_output.put_line('JOB
执行中的next_date: ' ||
                       to_char(p_nextdate,'YYYY-MM-DD HH24:MI:SS'));
  --
等待10秒再退出执行
  dbms_lock.sleep(seconds => 10);
end sp_test_next_date;


 


创建调用该存储过程的JOB,定义interval为每天一次,也就是这次执行以后,下次执行时间应该在1天以后。


 


SQL> variable jobno number;


SQL> BEGIN


  2  DBMS_JOB.SUBMIT(job => :jobno,


  3  what => 'sp_test_next_date;',


  4  next_date => SYSDATE,


  5  interval => 'SYSDATE+1');


  6  COMMIT;


  7  END;


  8  /


 


PL/SQL 过程已成功完成。


 


jobno


---------


1


 


然后我们手工执行存储过程,执行完毕以后再手工从user_jobs视图中获得JOB的下次执行时间,可以看到在存储过程中修改的JOB的下次执行时间已经生效,变成了当前时间的30分钟以后,而不是默认的1天以后。


 


SQL> conn kamus


请输入口令:


已连接。


SQL> set serverout on


SQL> exec sp_test_next_date();


JOB执行中的next_date: 2004-12-02 00:44:11


 


PL/SQL 过程已成功完成。


 


SQL> col next_date for a20


SQL> select to_char(next_date,'YYYY-MM-DD HH24:MI:SS') next_date from user_jobs


where what = 'sp_test_next_date;';


 


NEXT_DATE


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


2004-12-02 00:44:11


 


我们再手工运行JOB,看看这次的结果,可以发现JOB没有运行完毕以前被修改了的下次运行时间跟JOB运行完毕以后再次手工检索user_jobs视图获得的下次运行时间已经不相同了。由此我们可以得出一个结论,next_date是在JOB运行完毕以后被Oracle自动修改的,而不是在JOB刚开始运行的时候,因为我们在存储过程中修改的next_dateJOB运行结束之后又被修改为默认的1天以后了。


 


SQL> exec dbms_job.run(1);


JOB执行中的next_date: 2004-12-02 00:54:52


 


PL/SQL 过程已成功完成。


 


SQL> select to_char(next_date,'YYYY-MM-DD HH24:MI:SS') next_date from user_jobs


where what = 'sp_test_next_date;';


 


NEXT_DATE


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


2004-12-03 00:24:52


 


现在我们再次修改存储过程,输出存储过程开始执行的时间,便于跟执行完毕以后的JOB下次执行时间进行比较。


 


create or replace procedure sp_test_next_date as
  p_jobno    number;
  P_nextdate date;
begin
  --
输出JOB刚开始执行的时间
  dbms_output.put_line(' JOB开始执行的时间: ' ||
                       to_char(sysdate, 'YYYY-MM-DD HH24:MI:SS'));
  --
将调用此存储过程的jobnext_date设置为30分钟以后
  select job into p_jobno from user_jobs where what = 'sp_test_next_date;';
  execute immediate 'begin dbms_job.next_date(' || to_char(p_jobno) || ',sysdate+1/48);commit;end;';
  --
修改完毕以后检查user_jobs视图,输出job目前的next_date
  select next_date
    into P_nextdate
    from user_jobs
   where what = 'sp_test_next_date;';
  dbms_output.put_line(' JOB
执行中的next_date: ' ||
                       to_char(p_nextdate,
你浏览的文章是 - 《Oracle作业(JOB)更新next_date的探讨》!
文章出处:https://www.procedurelife.com/content/ckal.html

0% (0)
0% (0)
评论0
游客
1 2