Oracle 11g调用dbms_scheduler报ORA-01870错误解决方案咨询
报错根本原因
ORA-01870报错的核心是你使用
TO_TIMESTAMP_TZ(日期字符串,格式)未指定时区时,Oracle默认继承会话时区,当日期落在会话时区的夏令时切换间隙(不存在的时间点/重复时间点)时,时间戳带时区的比较逻辑失效。你观察到仅夏季日期报错,刚好对应夏令时生效的时段,和推测一致。
解决方案
因为业务不需要时区支持,转换DATE到TIMESTAMP WITH TIME ZONE时,明确指定无夏令时规则的固定时区即可,推荐用UTC时区,完全避免夏令时问题:
DATE转TIMESTAMP WITH TIME ZONE的标准写法
用FROM_TZ函数指定固定时区,示例代码如下:
SET SERVEROUTPUT ON; DECLARE d_next_run_date TIMESTAMP WITH TIME ZONE; -- 业务侧DATE类型入参示例 v_start_date DATE := TO_DATE('04/06/2021', 'DD/MM/YYYY'); v_return_after DATE := TO_DATE('01/01/2022', 'DD/MM/YYYY'); BEGIN dbms_scheduler.evaluate_calendar_string( calendar_string => 'FREQ=DAILY;INTERVAL=15', start_date => FROM_TZ(CAST(v_start_date AS TIMESTAMP), 'UTC'), return_date_after => FROM_TZ(CAST(v_return_after AS TIMESTAMP), 'UTC'), next_run_date => d_next_run_date ); dbms_output.put_line(d_next_run_date); END; /
如果是直接写死日期字符串,也可以直接在TO_TIMESTAMP_TZ里指定时区:TO_TIMESTAMP_TZ('01/01/2022 00:00:00 UTC', 'DD/MM/YYYY HH24:MI:SS TZR')
注意事项
- 选择UTC的原因是该时区无夏令时规则,不会出现时间不存在/重复的情况,完全规避夏令时导致的比较错误
- 所有入参的时区保持统一即可,如果你不想用UTC,也可以指定固定偏移量的时区,比如
'+08:00',同样不会有夏令时问题
内容的提问来源于stack exchange,提问作者Vitor Mira
相关产品推荐
相关产品推荐

