Дата недействительна для указанного месяца - PullRequest
0 голосов
/ 31 декабря 2011

У меня проблема при выполнении этого оператора 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)  

Не могли бы вы сказать мне, что не так?

Ответы [ 2 ]

7 голосов
/ 31 декабря 2011

Во-первых, почему вы используете systimestamp? Если вы хотите это в месяц, то, конечно, sysdate достаточно точно? Во-вторых, мне нравится - то есть, это личное предпочтение - чтобы было предельно ясно, что происходит. Oracle имеет функцию add_months, которая будет делать то, что вы хотите. Таким образом, ваш запрос может быть легко:

SELECT * 
  FROM tbl_content
 WHERE last_updated >= add_months(sysdate, -1) 
 ORDER BY last_updated desc
4 голосов
/ 02 января 2012

Что на самом деле неправильно, так это то, что интервальная арифметика не корректирует дни - см. 6-ую ссылку в ссылке:

Когда интервальные вычисления возвращают значение datetime, результатом должно быть фактическое значение datetime, или база данных возвращает ошибку.

ADD_MONTHS делает; как эта ссылка говорит:

Если дата является последним днем ​​месяца или если в результирующем месяце меньше дней, чем в компоненте дня, то результатом является последний день результирующего месяца.

Итак, ADD_MONTHS(DATE '2011-12-31', -1) дает вам 2011-11-30, в то время как DATE '2011-12-31' - INTERVAL '1' MONTH пытается дать вам 2011-11-31, что, как говорится в сообщении, не является действительной датой.

(Это спорный вопрос, если такое поведение на самом деле не так,. Это неожиданно, но я считаю, что это соответствует требованиям ANSI Там может быть раз вы хотите, чтобы работать так, хотя я не могу думать о какой-то ...)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...