日期问题:TO_DATE()

时间:2015-11-18 23:26:46

标签: sql oracle

我尝试审核一些数据,以查找 report_name 字段的会计年度与 report_date 字段不匹配的位置。

表:交易

字段: report_name (始终以当前会计年度的最后两位数结尾。例如" transactions15" 2015财年)

report_date 应该是特定会计年度内的日期。

我们的财政年度从7月1日到6月30日。

这是我到目前为止所拥有的:

SELECT report_name, report_date
FROM reports
WHERE report_date 
BETWEEN 
  TO_DATE('01-JUL-' || (SUBSTR(report_name,-2) - 1),'DD-MON-YY')
AND
  TO_DATE('30-JUN-' || (SUBSTR(report_name,-2)),'DD-MON-YY')

不幸的是,我收到了错误:

ORA-01841 :(完整)年份必须介于-4713和+9999之间,而不是0。

我认为SUBSTR(report_name,-2)一定是问题吗?但是,我能够在查询中显示错误,因此我很困惑。

2 个答案:

答案 0 :(得分:2)

更好地改变你的逻辑:

WHERE report_name NOT LIKE '%' || TO_CHAR(ADD_MONTHS(report_date,-6), 'yy')

答案 1 :(得分:1)

问题在于你有-1减少年份。如果您的报告名称以00结尾,例如transaction00,你最终将连锁年份定为-1。你有效地做了:

select to_date('01-JUL--1', 'DD-MON-YY') from dual;

也得到:

ORA-01841: (full) year must be between -4713 and +9999, and not be 0

您可以使用原始的最后两位数来避免这种情况,并使用其他机制返回一年,例如add_months()

SELECT report_name, report_date
FROM reports
WHERE report_date 
BETWEEN 
  ADD_MONTHS(TO_DATE('01-JUL-' || (SUBSTR(report_name,-2)),'DD-MON-RR'), -1)
AND
  TO_DATE('30-JUN-' || (SUBSTR(report_name,-2)),'DD-MON-RR')

SQL Fiddle显示转换现在有效。

我已经将格式模型从YY更改为RR,因为如果你有2000年的记录,你可能有1999年或更​​早的记录,而YY值'99'将被视为2099而不是1999。

使用月份名称或缩写词取决于NLS语言,因此使用月份数字会更安全;或者你可以覆盖日期语言作为查询的一部分,但更多的是打字。

另请注意,between包含在内,但仅限于6月30日的午夜。如果你在那天晚些时候有其他时间,他们将被错过。