Oracle计划程序作业-间隔函数

g0czyy6m  于 2023-08-03  发布在  Oracle
关注(0)|答案(3)|浏览(117)

希望有人能帮忙,我正在将DBMS_JOBS更改为DBMS_SCHEDULER作业。目前,我们的DBMS_JOB使用INTERVAL函数,该函数查询一个带有运行时间列表的表,并从SYSDATE返回下一个时间。时间在一天中并不是均匀分布的,所以使用'FREQ= HOURLY'之类的东西不太有效。
我找不到任何类似的东西来为计划程序作业执行此操作。我错过了什么吗?
提前感谢:)

-- DBMS_JOB
INTERVAL = stk_HHD.SetNext

--Interval Function
FUNCTION SetNext
    RETURN  DATE
IS
    PfldNext    DATE;
BEGIN

    SELECT MIN(MOD(MOD(transfer-SysDate,1)+1,1))+SysDate INTO PfldNext
      FROM stk_Schedule
     WHERE source = 'HHD'
    ;

    RETURN NVL(PfldNext,TRUNC(SysDate,'MI')+1);

END SetNext;

-- Data
SOURCE TRANSFER          
------ ------------------
HHD    01-APR-08 02:45:00
HHD    01-APR-08 06:45:00
HHD    01-APR-08 08:15:00
HHD    01-APR-08 09:45:00
HHD    01-APR-08 11:15:00
HHD    01-APR-08 12:45:00
HHD    01-APR-08 14:15:00
HHD    01-APR-08 15:45:00
HHD    01-APR-08 17:15:00

字符串
编辑:添加了更多细节。

bprjcwpo

bprjcwpo1#

DBMS_SCHEDULER作业支持旧版DBMS_JOB间隔语法。虽然他们有一个更新的更强大的语法可用,遗留工作得很好,对于那些习惯它可能更简单的工作(我发现这是我自己的情况)。
至于调用一个函数,它也可以工作:

CREATE OR REPLACE FUNCTION f_my_repeat_interval
  RETURN date
AS
BEGIN
  RETURN SYSDATE + 30/1440; -- whatever logic you need
END;

BEGIN
  dbms_scheduler.create_job(job_name=>'TESTJOB',
                            job_type=>'PLSQL_BLOCK',
                            job_action=>'BEGIN NULL; END;', -- just for testing
                            repeat_interval => 'f_my_repeat_interval',
                            enabled => TRUE);
END;

字符串
至少在19c中是这样的。它动态执行repeat_interval代码,该代码触发一个函数并返回一个日期,该日期将成为下一个运行日期。

3hvapo4f

3hvapo4f2#

也许基于事件的调度程序作业可以解决您的问题。
示例详细信息在下面的链接中给出。

-- add an event queue subscriber for this user's messages
exec dbms_scheduler.add_event_queue_subscriber('crcagent')

-- create the first job and have it raise an event whenever it completes
-- (succeeds, fails or stops),
-- (Not anymore :in this case it should fail with an error due to lack of ";" at the end of the insert statement
begin
dbms_scheduler.create_job
( 'first_job', job_action =>
'insert into job_output values(systimestamp, ''first job runs'');',
job_type => 'plsql_block',
enabled => false, repeat_interval=>'freq=secondly;interval=30' ) ;
dbms_scheduler.set_attribute
( 'first_job' , 'raise_events' , dbms_scheduler.job_run_completed);
end;
/

-- create a procedure that retrieves the status of first_job from the message
create or replace procedure second_proc
(message IN sys.scheduler$_event_info) as
msg_text varchar2(4000);
begin
-- compose the message
msg_text :=
'Job: "'||message.object_owner||'"."'||message.object_name||'"
Event: '|| message.event_type || '
Date: '|| regexp_replace(message.event_timestamp,'\.[0-9]{3,}') || '
Error code: ' || message.error_code|| '
Error message:
' || message.error_msg;

-- insert into job output
insert into job_output values (systimestamp,
'first_job has completed, status is '||msg_text);
end;
/

-- create a program that the second job runs, so we can get the status of
-- the first job using a metadata argument
begin
dbms_scheduler.create_program (
program_name => 'second_prog',
program_action=> 'second_proc',
program_type => 'stored_procedure',
number_of_arguments => 1,
enabled => FALSE) ;

dbms_scheduler.define_metadata_argument (
'second_prog','event_message',1);

dbms_scheduler.enable('second_prog');
end;
/

-- create the second job that runs whenever the first job completes
begin
dbms_scheduler.create_job('second_job',
program_name => 'second_prog',
event_condition =>
'tab.user_data.object_name = ''FIRST_JOB''',
queue_spec =>'sys.scheduler$_event_queue,crcagent',
enabled=>true);
end;
/

-- finally enable the first_job so it starts running
exec dbms_scheduler.enable('first_job')

字符串
Event Based Job Example

r3i60tvu

r3i60tvu3#

根据您提供的计划,您可以创建两个计划并将它们合并

BEGIN
DBMS_SCHEDULER.CREATE_SCHEDULE('s1', repeat_interval => 'FREQ=MINUTELY;BYHOUR=2,6,9,12,15;BYMINUTE=45');

DBMS_SCHEDULER.CREATE_SCHEDULE('s2', repeat_interval => 'FREQ=MINUTELY;BYHOUR=8,11,14,17;BYMINUTE=15');

DBMS_SCHEDULER.CREATE_SCHEDULE('s3', repeat_interval => 'FREQ=MINUTELY;INTERSECT=s1,s2');

END;
/

字符串
然后,您可以在工作中使用此计划。

相关问题