简体   繁体   English

日期对指定的月份无效

[英]Date not valid for month specified

I have a problem when running this Oracle SQL statement: 运行此Oracle SQL语句时出现问题:

SELECT * 
  FROM tbl_content
 WHERE last_updated >= (systimestamp - INTERVAL '1' month(1)) 
 ORDER BY last_updated desc  

And this error: 而这个错误:

    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)  

Could you tell me what is wrong? 你能告诉我怎么了吗?

Firstly, why are you using systimestamp ? 首先,为什么要使用systimestamp If you want this to the month then surely sysdate is exact enough? 如果您想要这个月,那么sysdate是否足够准确? Secondly, I like - ie it's personal preference - to make it extremely clear what's happening. 其次,我喜欢-即个人喜好-非常清楚正在发生的事情。 Oracle has an add_months function, which will do what you want. Oracle具有add_months函数,它将执行您想要的操作。 So your query could easily be: 因此,您的查询很容易是:

SELECT * 
  FROM tbl_content
 WHERE last_updated >= add_months(sysdate, -1) 
 ORDER BY last_updated desc

What is actually wrong is that interval arithmetic doesn't adjust days - see the 6th bullet in the link: 实际的错误是间隔算术无法调整天数-请参阅链接中的第6个项目符号:

When interval calculations return a datetime value, the result must be an actual datetime value or the database returns an error. 当间隔计算返回日期时间值时,结果必须是实际的日期时间值,否则数据库将返回错误。

ADD_MONTHS does; ADD_MONTHS可以; as that link says: 如该链接所述:

If date is the last day of the month or if the resulting month has fewer days than the day component of date, then the result is the last day of the resulting month. 如果日期是该月的最后一天,或者如果结果月份的天数少于日期的天部分,则结果是结果月份的最后一天。

So, ADD_MONTHS(DATE '2011-12-31', -1) gives you 2011-11-30, while DATE '2011-12-31' - INTERVAL '1' MONTH tries to give you 2011-11-31, which as the message says, isn't a valid date. 因此, ADD_MONTHS(DATE '2011-12-31', -1)会给您2011-11-30,而ADD_MONTHS(DATE '2011-12-31', -1) DATE '2011-12-31' - INTERVAL '1' MONTH会给您2011-11-31,如消息所示,这不是有效日期。

(It's debatable if this behaviour is actually wrong; it's unexpected, but I believe it's conforming to ANSI. There may be times you want it to work this way, though I can't think of any...) (如果这种行为实际上是错误的,则值得商;;这是出乎意料的,但是我相信它符合ANSI。有时候,您可能希望它以这种方式工作,尽管我想不到……)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM