Oracle 服务器中的日期构造“Oracle 数据库错误 1839”

Posted

技术标签:

【中文标题】Oracle 服务器中的日期构造“Oracle 数据库错误 1839”【英文标题】:Date Construction in Oracle Server "Oracle database error 1839" 【发布时间】:2017-04-21 15:40:48 【问题描述】:

抱歉,我对 Oracle SQL 很陌生,所以这可能有一些令人眼花缭乱的错误!

当我将以下语句作为查询的一部分运行时,会出现以下错误: “Oracle 数据库错误 1839:ORA-01839:指定月份的日期无效”

我认为这与闰年有关,因为当我过滤我的时间序列以获取最近的数据(3 月-当前日期)时,不会给出错误

提前致谢

(TO_CHAR(extract(year from TO_DATE('01/01/2000','DD/MM/YYYY')), '9999') 
- 
(
TO_CHAR(extract(year from "DELIVERY_DATE"), '9999') 
- TO_CHAR(extract(year from "TRADING_DATE"), '9999')
)
)

|| TO_CHAR(extract(month from "TRADING_DATE"), 'FM00') 
|| TO_CHAR(extract(day from "TRADING_DATE"), '99')

,'YYYYMMDD') 

【问题讨论】:

你说得对。年份部分可能是 1999 年或 1998 年,具体取决于交货日期和交易日期之间的差异。因此,如果月份部分是 2 月,而日期部分是 29;你会得到一个错误。在执行其余的 SQL 之前,您需要先检查年份部分是闰年。这是检查闰年的功能:dba-oracle.com/t_detect_leap_year_function.htm 这段代码有几个问题。比如你调用TO_CHAR,它会输出字符串。然后你从另一个字符串中减去一个字符串。 Oracle 是宽容的——它将字符串转换回数字——运气好的话,Oracle 会正确处理(但是,有时它确实会出错)。如果您首先解释您要解决的问题,而不是修复您的代码,您可能会获得更好的帮助;我只是猜测可能存在一个更简单的解决方案。 @mathguy,是的,我们可以改进 sql,因为它所做的是从交易日期复制月份和日期,然后从 2000 年减去交货日期和交易日期之间的年份差。希望清楚。 表达式TO_CHAR(extract(year from TO_DATE('01/01/2000','DD/MM/YYYY')), '9999') 可以替换为简单的'2000' 我还是不明白你想要达到什么目的。请edit您的问题并添加一些示例数据和基于该数据的预期输出。 【参考方案1】:

由于您从 2000 年(闰年)中减去年份,我将更改您的 SQL 以检查 DELIVERY_DATE 和 TRADING_DATE 之间的差异是否不能被 4 整除;如果不能被 4 整除(比如 1999 年不是闰年,月份是 2 月 29 日,则使用 1999 年 2 月 28 日)。这仅在您将参考年固定为闰年 2000 年时才有效。如果您更改参考年份 2000,我可以给您另一个答案。希望这会有所帮助。

 SELECT TO_DATE(
      CASE WHEN mod(extract(year from "DELIVERY_DATE") - extract(year from "TRADING_DATE"),4)!=0
            AND to_char("TRADING_DATE", 'mm/dd') = '02/29'
    then to_char(extract(year from TO_DATE('01/01/2000','DD/MM/YYYY')) - 
           extract(year from "DELIVERY_DATE") + 
           extract(year from "TRADING_DATE")) ||
           to_char("TRADING_DATE" - 1, 'mmdd')  
    else to_char(extract(year from TO_DATE('01/01/2000','DD/MM/YYYY')) - 
           extract(year from "DELIVERY_DATE") + 
           extract(year from "TRADING_DATE")) ||
           to_char("TRADING_DATE", 'mmdd') 
    END,'YYYYMMDD')  AS ANSWER 
    FROM DUAL;

【讨论】:

表达式to_char(extract(year from TO_DATE('01/01/2000','DD/MM/YYYY'))可以替换为简单的'2000',但实际上应该是2000(数字而不是字符串)

以上是关于Oracle 服务器中的日期构造“Oracle 数据库错误 1839”的主要内容,如果未能解决你的问题,请参考以下文章

ORACLE 參数文件介绍

Oracle

centos安装oracle 11g 完全图解

用otl写的oracle取数工具,执行传入在查询语句,把结果输出到文件

时间戳转为日期格式

12c 中的 Oracle 日期格式 9999-06-15T00:00:00.000+0000