首页 文章

在Oracle 11g DBMS_SCHEDULER的repeat_interval中使用PL / SQL表达式

提问于
浏览
3

我试图将PL / SQL表达式设置为我的工作的REPEAT_INTERVAL - 不幸的是,它不起作用 .

我希望在这样的时间间隔内包含CASE表达式,例如,如何设置作业的重复间隔在一分钟内开始,让我们说在14:17:00,如果它运行在偶数分钟它运行在30下一次秒,如果它在奇数分钟运行,它将在下一分钟开始,所以它的运行时间表看起来像:

14:17:00
14:18:00
14:18:30
14:19:00
14:20:00
14:20:30
14:21:00

等等 . 我尝试过这些表达式:

trunc(sysdate, 'MI') + CASE WHEN mod(to_number(to_char(sysdate, 'MI')), 2)=0 then (1/24/60/2) else (1/24/60) end case
SYSTIMESTAMP + CASE WHEN mod(to_number(to_char(sysdate, 'MI')), 2)=0 then INTERVAL '30' SECOND else INTERVAL '60' SECOND end case

他们都在SQL查询中工作,但我无法编译JOB . 这样的PL / SQL表达式应该如何?

或者,有没有办法让JOB在运行时计算下一个运行日期?我还尝试在每次作业运行时修改开始日期,但没有成功 - 看起来作业在第一次运行时仅使用开始日期一次,而且从未再次使用,即使日期在未来日期更改 .

2 回答

  • 2

    据我所知,the documentation,如果你这样做,这应该是可能的

    • 创建两个时间表;一分钟,一分钟,奇数分钟

    • 其中一个时间表包括另一个

    • 配置您的作业以使用组合计划

    文档中的示例:

    BEGIN
      dbms_scheduler.create_schedule('embed_sched', repeat_interval =>
        'FREQ=YEARLY;BYDATE=0130,0220,0725');
      dbms_scheduler.create_schedule('main_sched', repeat_interval =>
        'FREQ=MONTHLY;INTERVAL=2;BYMONTHDAY=15;BYHOUR=9,17;INCLUDE=embed_sched');
    END;
    
  • 3

    我猜它有点迟到的答案,但比以后更好 . 你可以在重复间隔内使用plssql函数:

    测试时间:11.2.0.3.0

    让我们创造功能 . my_schedules.odd_even如果当前分钟为偶数则返回current_date 30秒,如果当前分钟为奇数则返回1分钟:

    CREATE OR REPLACE package my_schedules
    is
    function odd_even(p_date date default sysdate) return date;
    end;
    </code>
    <code>
    CREATE OR REPLACE package body my_schedules  
    is
    
    -- even - 30 seconds
    -- odd - 1 minute;
    function odd_even(p_date date default sysdate) 
    return date
    is
    l_ret date;
    l_sec_in_day number := 60*60*24;
    begin
    
    case mod( (to_number(to_char(sysdate,'MI'))) ,2)
    when 0 then 
    --- even return 30 seconds
    l_ret:= SYSDATE + 30/l_sec_in_day;
    else 
    -- odd return a minute
    l_ret:= SYSDATE + 60/l_sec_in_day;
    end case;
    return l_ret;
    end;`enter code here`
    
    end;
    /
    

    使用repeat_interval = my_schedules.odd_even创建作业并启用作业:

    declare
      l_action varchar2(2000);
      l_repeat_interval varchar2(250) := 'my_schedules.odd_even';
      l_job_name varchar2(30) := 'TESTING_PLSSQL_SCH';
      begin  
        l_action := 'declare dummy number; begin dummy := 1; end;';
    
        dbms_scheduler.create_job(job_name        => '"'|| l_job_name||'"',
                                  job_type        => 'plsql_block',
                                  job_action      => l_action,
                                  start_date      => sysdate,
                                  repeat_interval => l_repeat_interval,
                                  comments        => 'just a test'
                                  );
    
        dbms_scheduler.enable(name => '"'||l_job_name||'"');                              
     end;
    

    我们暂时检查一下结果:

    select job_name, actual_start_date  from DBA_SCHEDULER_JOB_RUN_DETAILS rd where job_name = 'TESTING_PLSSQL_SCH' order by actual_start_date;
    
    job_name |  actual_start_date
    --------------------------
    TESTING_PLSSQL_SCH  2016/07/14/ 17:33:36,671977 +03:00
    TESTING_PLSSQL_SCH  2016/07/14/ 17:34:36,007573 +03:00
    TESTING_PLSSQL_SCH  2016/07/14/ 17:35:06,006206 +03:00
    TESTING_PLSSQL_SCH  2016/07/14/ 17:36:06,001652 +03:00
    TESTING_PLSSQL_SCH  2016/07/14/ 17:36:36,005513 +03:00
    TESTING_PLSSQL_SCH  2016/07/14/ 17:37:06,003572 +03:00
    TESTING_PLSSQL_SCH  2016/07/14/ 17:38:06,011409 +03:00
    TESTING_PLSSQL_SCH  2016/07/14/ 17:38:36,011411 +03:00
    TESTING_PLSSQL_SCH  2016/07/14/ 17:39:06,011357 +03:00
    TESTING_PLSSQL_SCH  2016/07/14/ 17:40:06,002623 +03:00
    

    Oracle Database Online Documentation 11g第1版(11.1)/数据库管理/使用计划:here

相关问题