ORA-01870 试图将日期转换为带有时区的时间戳
Posted
技术标签:
【中文标题】ORA-01870 试图将日期转换为带有时区的时间戳【英文标题】:ORA-01870 trying to convert from date into timestamp with time zone 【发布时间】:2021-10-04 07:44:54 【问题描述】:在 Oracle DB 11g 上使用 SQL DEVELOPER 运行以下 PL/SQL 匿名块时
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 参数
【问题讨论】:
您的会话在哪个时区 (select sessiontimezone from dual
); select TO_TIMESTAMP_TZ('01/01/2022', 'DD/MM/YYYY') from dual
返回什么?
试试演员表。 `select cast (sysdate as timestamp with time zone) from dual;'
你真的喜欢半年后入职吗?
您使用的是哪个 Oracle 版本?我的是 12.2.0.1,在我的系统上你的代码运行得很好;没有抛出错误,程序正确打印下一次运行日期。
但是,我看到你的两个版本(原始代码和你说的那个有效)是相同的。您在发布此内容时是否犯了错误 - 也许您引发错误的代码不是您发布为“现有代码”的代码?
【参考方案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
【讨论】:
以上是关于ORA-01870 试图将日期转换为带有时区的时间戳的主要内容,如果未能解决你的问题,请参考以下文章