现项目有一需求要在ORACLE 10里设置一定时JOB,在每月的29号00:10分执行,计算该月29日0点到上月29日0点的一些数据.对于2月份,在润年的2月29日00:10分执行,在平年则在3月1日00:10分执行(为了计算1月29日0点到3月1日0点以前的数据),(注意,3月1日执行完后,接着在3月29日执行job,以计算3月1日到3月29日0点之间的数据)其他月份都为29日00:10分执行.用last_day + 天数的方法设置会不会有问题?请给出创建JOB的代码,谢谢.

解决方案 »

  1.   

    关注,firstday+28行不行:
    select trunc(to_date('20070202','yyyymmdd'),'mm')+28 from dual; 
      

  2.   

    其实楼主的日期就是每月的28号+1天。
    普通月份不用说了。普通2月,+1天就是3月1号。润2月,+1天就是2月29号。
    每月28号+1天就是上月底+29天。job如下:DECLARE
      X NUMBER;
    BEGIN
      SYS.DBMS_JOB.SUBMIT
        ( job       => X 
         ,what      => 'test;'
         ,next_date => to_date('29-10-2007 01:00:00','dd/mm/yyyy hh24:mi:ss')
         ,interval  => 'last_day(add_months(TRUNC(SYSDATE,''MM''),-1))+29'
         ,no_parse  => TRUE
        );
      SYS.DBMS_OUTPUT.PUT_LINE('Job Number is: ' || to_char(x));
    END;
    /
    commit;
    解释一下last_day(add_months(TRUNC(SYSDATE,''MM''),-1))+29。
    首先取出当前日期(本次执行job的日期)的所在月份TRUNC(SYSDATE,''MM'');
    然后取出上月add_months(TRUNC(SYSDATE,''MM''),-1);
    然后取出上月月底last_day(add_months(TRUNC(SYSDATE,''MM''),-1));
    然后+29天last_day(add_months(TRUNC(SYSDATE,''MM''),-1))+29。
    结束,接分。
      

  3.   

    to fenixshadow,你写的interval好像不对,如果当前是10.29,按你写的interval还是10.29。
    to wylbob,实际上可以job设置为每天的0:10运行存储过程,然后在存储过程中判断是否是29日或是平年的3.1,如果是就计算。
      

  4.   

    楼上说的不错,只顾考虑特殊情况了。修改如下:
    DECLARE
      X NUMBER;
    BEGIN
      SYS.DBMS_JOB.SUBMIT
        ( job       => X 
         ,what      => 'test;'
         ,next_date => to_date('29-10-2007 01:00:00','dd/mm/yyyy hh24:mi:ss')
         ,interval  => 'decode(TRUNC(SYSDATE,''DD''),to_date(''0301'',''MMDD''),TRUNC(SYSDATE,''MM'')+28,add_months(TRUNC(SYSDATE,''MM''),+1))+28'
         ,no_parse  => TRUE
        );
      SYS.DBMS_OUTPUT.PUT_LINE('Job Number is: ' || to_char(x));
    END;
    /commit;就是说如果当前日期是3月1号的话,那么就把下次执行日期设置为本月29号。如果不是3月1号的话,那么就把日期设为下月1号+28天。
      

  5.   

    少了个括号
    DECLARE
      X NUMBER;
    BEGIN
      SYS.DBMS_JOB.SUBMIT
        ( job       => X 
         ,what      => 'test;'
         ,next_date => to_date('29-10-2007 01:00:00','dd/mm/yyyy hh24:mi:ss')
         ,interval  => 'decode(TRUNC(SYSDATE,''DD''),to_date(''0301'',''MMDD''),TRUNC(SYSDATE,''MM'')+28,add_months(TRUNC(SYSDATE,''MM''),+1))+28)'
         ,no_parse  => TRUE
        );
      SYS.DBMS_OUTPUT.PUT_LINE('Job Number is: ' || to_char(x));
    END;
    /commit;
      

  6.   

    考虑用别的方式,为什么不设置为每天晚上执行了,然后在过程中判断是否特定的时间?
    不要把判断时间的任务交给JOB,而是交给JOB对应的过程中.