【问题标题】:Can not Run Completed Oracle Job again无法再次运行已完成的 Oracle 作业
【发布时间】:2019-09-23 04:46:29
【问题描述】:

无法通过删除 END_DATE 来运行已完成的 DBMS_SCHEDULER 作业

大家好! 我正在使用 oracle 12cR1,现在我在 DBMS_SCHEDULER 工作中遇到了问题。

首先,我创建了一个重复的 oracle DBMS_SCHEDULER 作业,并设置了END_DATE, 设置END_DATE后,作业成功完成,作业的启用状态自动变为禁用。 根据作业的运行日志,Operation 为COMPLETED,而 Additional info 为REASON="End time reached" 这是意料之中的。

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

SYS.DBMS_SCHEDULER.SET_ATTRIBUTE('JOB_XXX', 'END_DATE', '');

并通过

设置作业启用
SYS.DBMS_SCHEDULER.ENABLE(name => 'JOB_XXX');

我可以看到该作业再次启用并且 END_DATE 为空。 但是Job只运行了一次就停止了,运行日志是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;
/

我的预期是作业将再次按照REPEAT_INTERVAL 运行, 由于end_date 是空的,它不应该停止。

删除END_DATE有什么错误,还是oracle的bug?

提前致谢,并致以最诚挚的问候!

【问题讨论】:

  • 猜猜看:DBMS_SCHEDULER.set_attribute_null (name=>'JOB_3358', attribute=>'end_date')
  • 我试过了,没用,工作停止了。还是谢谢!
  • 也许that link可以帮助你实现你的目标-

标签: oracle oracle12c dbms-scheduler


【解决方案1】:

棘手的一个。我重现了你的问题。然后,我尝试在删除 end_date 时将 start_date 更改为 systimestamp,但同样不起作用。但是,然后我在删除 end_date 时将 start_date 更改为 systimestamp 加上一点,然后它就起作用了。下面的工作示例。似乎有关该作业的一些信息被缓存/存储在某处,我们可以通过将 start_date 稍微设置为将来来删除此信息,以便在启用该作业时触发调度逻辑(我对发生的事情的疯狂理论)。删除已完成工作的 end_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');

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

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');

【讨论】:

  • 哇,干得好。您必须运行引发异常的命令才能使作业运行,这太疯狂了。
  • 谢谢,作业似乎被缓存/存储了,因为第二天我再次启用了作业(当 end_date 为空时),它开始运行并且不会再停止了。由于作业是通过 Windows 窗体创建的(不直接使用 oracle 客户端),当单击窗体上的保存按钮时,我发回两个命令来设置 end_date,第一个将 end_date 设置为 2999/12/31,然后第二个将 end_date 设置为 null,因此作业将在 2999/12/31 停止
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-30
  • 2015-12-17
  • 1970-01-01
  • 2021-12-26
  • 1970-01-01
  • 2016-11-09
  • 2016-05-27
相关资源
最近更新 更多