无法再次运行已完成的Oracle作业

fro*_*861 9 oracle dbms-scheduler oracle12c

无法DBMS_SCHEDULER通过删除END_DATE

大家好!我正在使用oracle 12cR1,现在DBMS_SCHEDULER作业有问题。

首先,我DBMS_SCHEDULER用END_DATEset 创建了一个重复的oracle 作业,在set之后END_DATE,作业成功完成,并且job的启用状态自动更改为Disabled。根据作业的运行日志,“操作”为COMPLETED,而“附加信息REASON="End time reached" ”为预期值。

然后我想再次运行作业,我删除了该END_DATE字段

SYS.DBMS_SCHEDULER.SET_ATTRIBUTE('JOB_XXX', 'END_DATE', '');
Run Code Online (Sandbox Code Playgroud)

并通过以下方式设置作业启用

SYS.DBMS_SCHEDULER.ENABLE(name => 'JOB_XXX');
Run Code Online (Sandbox Code Playgroud)

我可以看到该作业已再次启用,并且END_DATE为空。但是作业再次运行一次,然后停止,运行日志为COMPLETED,而附加信息REASON="End time reached"再次运行。

BEGIN
     sys.dbms_scheduler.CREATE_JOB(
     JOB_NAME            => 'JOB_3358',
     job_type            => 'STORED_PROCEDURE',
     JOB_ACTION          => 'TEST_JOB',
     START_DATE          => to_date('2019-05-05 13:35:00','yyyy-mm-dd hh24:mi:ss'),
     REPEAT_INTERVAL     => 'FREQ= SECONDLY;INTERVAL=30',
     END_DATE            => to_date('2019-05-05 13:38:00','yyyy-mm-dd hh24:mi:ss'),
     auto_drop           => FALSE,
     COMMENTS            => NULL);
    END;
/


begin
  sys.dbms_scheduler.enable(name => 'JOB_3358');
end;
/
Run Code Online (Sandbox Code Playgroud)

我所期望的是,该作业将REPEAT_INTERVAL再次运行,并且就像end_date空的一样,它永远都不应停止。

删除是否有任何错误END_DATE,还是这是oracle的错误?

在此先感谢您,并致以最诚挚的问候!

Pet*_*ter 4

棘手的一个。我重现了你的问题。然后,我尝试在删除 end_date 时将 start_date 更改为 systimestamp,但这又不起作用。但是,然后我在删除 end_date 时将 start_date 更改为 systimestamp 再加上一点,然后它就起作用了。下面的工作示例。似乎有关作业的一些信息被缓存/存储在某个地方,我们可以通过将 start_date 设置为稍微未来一些来删除此信息,以便在启用作业时触发调度逻辑(我对发生的情况的疯狂理论)。删除已完成作业的结束日期的工作示例:

BEGIN
     sys.dbms_scheduler.CREATE_JOB(
     JOB_NAME            => 'MYUSER.JOB_3358',
     job_type            => 'PLSQL_BLOCK',
     JOB_ACTION          => 'begin null; end;',
     START_DATE          => systimestamp,
     REPEAT_INTERVAL     => 'FREQ= SECONDLY;INTERVAL=30',
     END_DATE            => systimestamp + interval '2' minute,
     auto_drop           => FALSE,
     COMMENTS            => NULL);
    END;
/

begin
  sys.dbms_scheduler.enable(name => 'MYUSER.JOB_3358');
end;
/

-- wait until job shows as completed

exec DBMS_SCHEDULER.set_attribute_null (name=>'MYUSER.JOB_3358', attribute=>'end_date');

begin
          dbms_scheduler.set_attribute (
            name      => 'MYUSER.JOB_3358',
            attribute => 'start_date',
            value     => systimestamp + interval '1' minute);
    end;
    /

begin
  sys.dbms_scheduler.enable(name => 'MYUSER.JOB_3358');
end;
/

-- job will continue to run every 30 seconds indefinitely

--cleanup
exec sys.dbms_scheduler.drop_JOB(     JOB_NAME            => 'MYUSER.JOB_3358');
Run Code Online (Sandbox Code Playgroud)

编辑:上面的方法并不可靠。有时它会起作用,但并非总是如此。到目前为止,在我的测试中唯一可靠的(愚蠢的!!!)方法是:

exec DBMS_SCHEDULER.set_attribute_null (name=>'MYUSER.JOB_3358', attribute=>'end_date');
-- This line raises "ORA-27469: NEXT_RUN_DATE is not a valid job attribute" but is necessary.
exec DBMS_SCHEDULER.set_attribute_null (name=>'MYUSER.JOB_3358', attribute=>'next_run_date');
exec dbms_scheduler.enable(name => 'MYUSER.JOB_3358');
Run Code Online (Sandbox Code Playgroud)