1

我有一个创建 n 个工作的 Oracle For 循环。对于创建的每个作业,开始日期与上一个作业相隔 10 秒。但由于某种原因,每个作业都会在 1 秒内启动。未来的工作在 Oracle 中是不可能的吗?

    LTIMESTAMP := SYSTIMESTAMP;

    FOR REC IN (SELECT *
                  FROM ORDERS
                 WHERE PROCESS_FLAG = CST_IS_ELIGIBLE_FOR_PROCESSING
                 ORDER BY ORDER_DATE ASC)
    LOOP

        LJOBNAME := CST_JOB_NAME_PREFIX || TO_CHAR(REC.ORDER_ID);

        DBMS_SCHEDULER.CREATE_PROGRAM(PROGRAM_NAME        => CST_PROGRAM_NAME,
                                      PROGRAM_ACTION      => 'PKG_BATCH_MAIN.SP_START_JOB',
                                      PROGRAM_TYPE        => 'STORED_PROCEDURE',
                                      NUMBER_OF_ARGUMENTS => 2,
                                      ENABLED             => FALSE);

        DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT(PROGRAM_NAME      => CST_PROGRAM_NAME,
                                               ARGUMENT_POSITION => 1,
                                               ARGUMENT_TYPE     => 'NUMBER');

        DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT(PROGRAM_NAME      => CST_PROGRAM_NAME,
                                               ARGUMENT_POSITION => 2,
                                               ARGUMENT_TYPE     => 'NUMBER');

        DBMS_SCHEDULER.ENABLE(CST_PROGRAM_NAME);

        DBMS_SCHEDULER.CREATE_JOB(JOB_NAME        => LJOBNAME,
                                  PROGRAM_NAME    => CST_PROGRAM_NAME,
                                  START_DATE      => LTIMESTAMP,
                                  REPEAT_INTERVAL => 'FREQ=SECONDLY; BYSECOND=1',
                                  END_DATE        => NULL,
                                  AUTO_DROP       => TRUE,
                                  ENABLED         => FALSE,
                                  COMMENTS        => 'Job launched for each ORDER detail id');

            DBMS_SCHEDULER.SET_ATTRIBUTE(LJOBNAME,
                                         'MAX_RUNS',
                                         1);

            DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(LJOBNAME,
                                                  1,
                                                  TO_CHAR(REC.ORDER_ID));
            DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(LJOBNAME,
                                                  2,
                                                  TO_CHAR(REC.ORDER_DETAILS_ID));

            DBMS_SCHEDULER.ENABLE(LJOBNAME);

            LTIMESTAMP := LTIMESTAMP + INTERVAL '10' SECOND;

    END LOOP;
4

1 回答 1

0

我猜 LTIMESTAMP 是 insted 的timestamp数据类型TIMESTAMP WITH TIME ZONE。在自动转换期间,您会失去时间戳的准确性。

调度程序使用时区SELECT * FROM dba_scheduler_global_attribute WHERE attribute_name = 'DEFAULT_TIMEZONE';

在会话中,您使用的时区来自SELECT sessiontimezone FROM DUAL;

declare
 with_timestamp  TIMESTAMP WITH TIME ZONE := systimestamp;
 no_timestamp    timestamp                  := with_timestamp;
 auto_conversion TIMESTAMP WITH TIME ZONE := no_timestamp;
begin 
 dbms_output.put_line(to_char(with_timestamp,'YYYY-MM-DD hh24:mi:ss TZR')); 
 dbms_output.put_line(to_char(no_timestamp,'YYYY-MM-DD hh24:mi:ss TZR'));
 dbms_output.put_line(to_char(auto_conversion,'YYYY-MM-DD hh24:mi:ss TZR'));

end;

我的服务器的结果是

2017-05-11 09:15:44 +01:00
2017-05-11 09:15:44 +00:00
2017-05-11 09:15:44 +02:00

就我而言,所有工作将在一小时内开始。您的 start_date 早于调度程序的当前日期。

于 2017-05-11T08:31:45.850 回答