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”的主要内容,如果未能解决你的问题,请参考以下文章