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 在运行时计算它的下一个运行日期?我还尝试在每次作业运行时修改开始日期,但没有成功 - 看起来该作业在第一次运行时只使用一次开始日期,并且再也不会使用,即使日期已更改为将来的日期。

4

2 回答 2

3

据我从文档中可以看出,如果您这样做,这应该是可能的

  • 创建两个时间表;一个用于偶数分钟,一个用于奇数分钟
  • 有一个时间表包括另一个
  • 配置您的作业以使用组合计划

文档中的示例:

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;
于 2014-02-21T10:42:30.743 回答
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 数据库在线文档 11g 第 1 版 (11.1) / 数据库管理/使用计划:这里

于 2016-07-14T15:00:17.877 回答