问题描述
我目前陷入错误,我不清楚。
ORA-01843: not a valid month
01843. 00000 - "not a valid month"
*Cause:
*Action:
到目前为止,我在Stackoverflow上检查了几篇文章,但是对我没有太大帮助。 我有类似的查询
SELECT * FROM (
SELECT uta.StartDate,uta.EndDate
FROM user_timesheets_absence uta
LEFT JOIN users u
ON u.UserID = uta.UserID
AND uta.Approved = '0'
AND
((
'2020-01-30' >= TO_DATE(uta.StartDate,'YYYY-MM-DD')
AND
'2020-02-06' <= TO_DATE(uta.EndDate,'YYYY-MM-DD')
)
OR
(
'2020-01-30' <= TO_DATE(uta.StartDate,'YYYY-MM-DD')
AND
'2020-01-30' >= TO_DATE(uta.StartDate,'YYYY-MM-DD')
))
--GROUP BY uta.UserAbsenceID
UNION
SELECT ut.DATE_ AS StartDate,ut.DATE_ AS EndDate
FROM user_timesheets ut
INNER JOIN moments m ON
m.UserTimesheetsID = ut.UserTimesheetsID
WHERE
TO_DATE(ut.DATE_,'YYYY-MM-DD') BETWEEN '2020-01-21' AND '2020-01-30' + SYSTIMESTAMP + 1
AND ut.user_id = 1
) a
这是填充StartDate
和EndDate
的问题
我尝试使用“ TO_TIMESTAMP”并尝试将格式更改为VARCHAR2
,但不起作用。
老实说,到目前为止我还不知道我在哪里做错了。
我在哪里弄错了?这是怎么了?
更新
正如答案中的GMB所说,使用YYYY/MM/DD
会给出三餐无效的日期字符串。
与上面的查询相距甚远,当我运行它时,出现以下错误
validate_conversion()
解决方法
列中的某些字符串是无效日期。从版本12.2开始,很容易通过validate_conversion()
的函数to_date()
子句来展示它们。以下查询为您提供了所有无效的日期字符串:
select date_
from user_timesheets
where validate_conversion(date_ as date,'YYYY/MM/DD') = 0
然后您可以修复数据。
您应该考虑使用date
数据类型存储日期,以便在写入数据时加强完整性。
同时,让我建议优化过滤逻辑:字符串的格式可以使用直接过滤(无需事先转换为日期):效率更高,因为它不需要在过滤之前转换整个列(on表示谓词是SARGeable)。通常,您将替换以下内容:
to_date(uta.startdate,'yyyy/mm/dd') <= '2020-01-30'
使用:
ut.startdate <= '2020/01/30'
或者,如果要再次过滤当前系统日期,则:
ut.startdate <= to_char(sysdate,'YYYY/MM/DD')
,
并非所有startdate
和enddate
列都具有YYYY/MM/DD
格式的值,或者-如果确实如此,则它们是无效的。
例如:2020/A8/43
或ab3f/xy/2i
或2020/15/02
之类的值无效。
错误说这些字符串的MM
部分不在01
和12
之间。
首先,您应该使用date
而非字符串存储日期值。一种可能是这些实际上是 日期,而您无需重新转换它们。没有样本数据,很难说。但是您应该努力修复数据。
第二,Oracle中的日期常量应类似于:
DATE '2020-01-30'
所以:
DATE '2020-01-30' >= TO_DATE(uta.StartDate,'YYYY/MM/DD')