ORA-01839:日期对于指定的月份无效,如何避免闰年问题



我有一个表,为每个人存储有效的"自定义日期"。这个日期可能是闰年的2月29日。问题是,在我的SQL中,我需要从该员工最近一年的自定义日期字段中提取"最后"mm/dd。这个日期永远不会在未来,所以我可以比较日期中的年份,如果是当前年份,则按原样提取。但是,如果是前一年(可以追溯到1900年),则我需要提取该MM/DD和截至去年的日期。所以你可以看到,由于没有2018年2月29日,这将是一个问题。

我正在寻找如何处理这个问题的最佳解决方案。我需要它在我的选择部分和条件块中,我试图推导的日期必须>=applydtm日期。下面是一个用于复制错误的示例查询。只需将2月29日的日期切换到2月28日,就会显示它在工作,因为它不会遇到无效的闰年日期。如果需要,只要代码尽可能有效,我可以将2月29日的所有日期"转换"为3月1日。DB=Oracle 11g

WITH sampledata (actualcustomdtm, textfield, applydtm)  AS  (
SELECT
TO_DATE('02/29/2012 00:00:00','mm/dd/yyyy hh24:mi:ss'),
'Leap Year',
sysdate
FROM dual
UNION
SELECT
TO_DATE('01/15/2019 00:00:00','mm/dd/yyyy hh24:mi:ss'),
'Non-Leap Year',
sysdate
FROM dual
)
SELECT
actualcustomdtm,
CASE WHEN TO_CHAR(actualcustomdtm, 'YYYY') = TO_CHAR(SYSDATE, 'YYYY')
THEN TO_CHAR(actualcustomdtm, 'MM/DD/YYYY')
ELSE TO_CHAR(actualcustomdtm, 'MM/DD')||'/'||TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE), -12), 'YYYY')
END AS "LASTACTCSTMDATE",
textfield,
applydtm
FROM sampledata
WHERE applydtm >=
TO_DATE(CASE WHEN TO_CHAR(actualcustomdtm, 'YYYY') = TO_CHAR(SYSDATE, 'YYYY')
THEN TO_CHAR(actualcustomdtm, 'MM/DD/YYYY')
ELSE TO_CHAR(actualcustomdtm, 'MM/DD')||'/'||TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE), -12), 'YYYY')
END, 'MM/DD/YYYY')

我相信这个逻辑可以满足您的需求——将最近的周年纪念日设置为或包括今天的日期:

select dte, add_months(dte, 12),
(case when to_char(dte, 'MMDD') > to_char(sysdate, 'MMDD')
then add_months(dte, 12 * (extract(year from sysdate) - extract(year from dte) - 1))
else add_months(dte, 12 * (extract(year from sysdate) - extract(year from dte)))
end)
from (select date '2016-02-29' as dte from dual union all
select date '2018-01-03' from dual
) x;

最新更新