我尝试审核一些数据,以查找 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)一定是问题吗?但是,我能够在查询中显示错误,因此我很困惑。
答案 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日的午夜。如果你在那天晚些时候有其他时间,他们将被错过。