运行此Oracle SQL语句时遇到问题:
SELECT *
FROM tbl_content
WHERE last_updated >= (systimestamp - INTERVAL '1' month(1))
ORDER BY last_updated desc
这个错误:
java.sql.SQLException: ORA-01839: date not valid for month specified
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:111)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:330)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:287)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:742)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:212)
at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:951)
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1053)
at oracle.jdbc.driver.T4CPreparedStatement.executeMaybeDescribe(T4CPreparedStatement.java:835)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1123)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3284)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3328)
at com.vtdd.sms.content.xskt.XsktService.getKQXSFollowArea(XsktService.java:4044)
at com.vtdd.sms.content.xskt.XsktService.getMessages(XsktService.java:421)
at com.vht.sms.content.ContentAbstract.getSubmitMessages(ContentAbstract.java:47)
at com.vht.sms.content.ContentFactory.getSubmitMessages(ContentFactory.java:335)
at com.vht.sms.content.ContentFactory.run(ContentFactory.java:62)
at java.lang.Thread.run(Thread.java:662)
你能告诉我出了什么问题吗?
答案 0 :(得分:7)
首先,你为什么要使用systimestamp
?如果你想要这个月,那么肯定sysdate
就足够了吗?其次,我喜欢 - 即个人偏好 - 非常清楚发生了什么。 Oracle有一个add_months
函数,可以执行您想要的操作。所以你的查询很容易:
SELECT *
FROM tbl_content
WHERE last_updated >= add_months(sysdate, -1)
ORDER BY last_updated desc
答案 1 :(得分:4)
实际上错误的是interval arithmetic没有调整天数 - 请参阅链接中的第6个子弹:
当间隔计算返回日期时间值时,结果必须是实际的日期时间值,否则数据库将返回错误。
ADD_MONTHS
呢;正如那个链接所说:
如果日期是该月的最后一天,或者结果月份的日期少于日期的日期组成部分,那么结果就是结果月份的最后一天。
所以,ADD_MONTHS(DATE '2011-12-31', -1)
给你2011-11-30,而DATE '2011-12-31' - INTERVAL '1' MONTH
试图给你2011-11-31,正如消息所说,这不是一个有效的日期。
(如果这种行为实际上是错误的,这是有争议的;这是意料之外的,但我相信它符合ANSI。有时你可能希望它以这种方式工作,虽然我想不出任何......)