ORA-01870 试图将日期转换为带时区的时间戳

时间:2021-07-28 14:47:58

标签: oracle plsql dbms-scheduler

当以下 PL/SQL 匿名块在 Oracle DB 11g 上使用 SQL DEVELOPER 运行时

SET SERVEROUTPUT ON;

DECLARE
    d_next_run_date TIMESTAMP WITH TIME ZONE;
BEGIN
    dbms_scheduler.evaluate_calendar_string(
            calendar_string => 'FREQ=DAILY;INTERVAL=15', 
            start_date => TO_TIMESTAMP_TZ('04/06/2021', 'DD/MM/YYYY'),
            return_date_after => TO_TIMESTAMP_TZ('01/01/2022', 'DD/MM/YYYY'),
            next_run_date => d_next_run_date
            );

    dbms_output.put_line(d_next_run_date);
END;

抛出以下异常

ORA-01870: the intervals or datetimes are not mutually comparable
ORA-06512: at "SYS.DBMS_SCHEDULER", line 3599
ORA-06512: at line 4
01870. 00000 -  "the intervals or datetimes are not mutually comparable"
*Cause:    The intervals or datetimes are not mutually comparable.
*Action:   Specify a pair of intervals or datetimes that are mutually
           comparable.

我怀疑该问题与时区有关。

如果参数更改为以下,则不会抛出异常(注意我更改了传入参数return_date_after的值)

SET SERVEROUTPUT ON;

DECLARE
    d_next_run_date TIMESTAMP WITH TIME ZONE;
BEGIN
    dbms_scheduler.evaluate_calendar_string(
            calendar_string => 'FREQ=DAILY;INTERVAL=15', 
            start_date => TO_TIMESTAMP_TZ('04/06/2021', 'DD/MM/YYYY'),
            return_date_after => TO_TIMESTAMP_TZ('01/01/2021', 'DD/MM/YYYY'),
            next_run_date => d_next_run_date
            );

    dbms_output.put_line(d_next_run_date);
END;

或者如果参数更改为以下(我再次更改了传递给参数 return_date_after 的值)

SET SERVEROUTPUT ON;

DECLARE
    d_next_run_date TIMESTAMP WITH TIME ZONE;
BEGIN
    dbms_scheduler.evaluate_calendar_string(
            calendar_string => 'FREQ=DAILY;INTERVAL=15', 
            start_date => TO_TIMESTAMP_TZ('04/06/2021', 'DD/MM/YYYY'),
            return_date_after => TO_TIMESTAMP_TZ('01/06/2022', 'DD/MM/YYYY'),
            next_run_date => d_next_run_date
            );

    dbms_output.put_line(d_next_run_date);
END;

我必须满足的要求不需要支持时区。如果可能,我想将数据类型 DATE 与过程 dbms_scheduler.evaluate_calendar_string 一起使用。但是,dbms_scheduler.evaluate_calendar_string 参数属于 TIMESTAMP WITH TIMEZONE 类型。如何将 DATE 转换为 TIMESTAMP WITH TIMEZONE 并避免该异常?

我注意到当一个对应于夏天的日期值被传递到参数 return_date_after 时会抛出异常。因此该错误可能与夏令时有关。

数据库版本:11.2.0.1.0

nls 参数 enter image description here

1 个答案:

答案 0 :(得分:1)

我通过在将字符转换为 TIMESTAMP WITH TIMEZONE 时添加时间和时区来避免该错误

SET SERVEROUTPUT ON;

DECLARE
    d_next_run_date TIMESTAMP WITH TIME ZONE;
BEGIN
    dbms_scheduler.evaluate_calendar_string(
            calendar_string => 'FREQ=DAILY;INTERVAL=15', 
            start_date => TO_TIMESTAMP_TZ('04/06/2021 00:00:00 00:00', 'DD/MM/YYYY HH24:MI:SS TZH:TZM'),
            return_date_after => TO_TIMESTAMP_TZ('01/01/2022 00:00:00 00:00', 'DD/MM/YYYY HH24:MI:SS TZH:TZM'),
            next_run_date => d_next_run_date
            );

    dbms_output.put_line(d_next_run_date);
END;
/

输出

15/01/22 00:00:00,000000 +00:00
相关问题