Недопустимый месяц в oracle при использовании add_months

Я дал следующий код в запросе.

    where to_date(cal_wid,'yyyymmdd')
between  add_months(to_date(sysdate, 'MM-YYYY'),-12)
and      to_date(sysdate, 'MM-YYYY')

Я получаю следующую ошибку. (Я делаю на сервере Xampp)

   Warning: oci_execute(): ORA-01843: not a valid month in C:\xampp\htdocs\xxx\index.php on line 149

Warning: oci_fetch_array(): ORA-24374: define not done before fetch or execute and fetch in C:\xampp\htdocs\xxx\index.php on line 160

Может кто-нибудь сказать, почему я получаю эту ошибку?

2

Решение

Никогда, никогда не используйте TO_DATE() на то, что уже DATE, Причина этого заключается в том, что Oracle должен будет выполнить некоторые неявные преобразования, чтобы следовать вашим пожеланиям:

TO_DATE(sysdate, 'mm-yyyy')

действительно работает как

TO_DATE(TO_CHAR(sysdate, '<default nls_date_format parameter>'), 'mm-yyyy')

так что если для вашего nls_date_format установлено значение, отличное от ‘mm-yyyy’, у вас будут проблемы. Параметр nls_date_format по умолчанию — «DD-MON-YY», что, скорее всего, равно значению, заданному вами.

Если все, что вы хотели сделать, это добавить add_months к 1-му числу текущего месяца, то вам следует использовать TRUNC()Например:

add_months(trunc(sysdate, 'MM'),-12)


Вот доказательство неявного to_char, если вы to_date что-то, что уже является датой, как этого требует Lalit — план выполнения основного запроса, включающего to_date (sysdate):

SQL_ID  3vs3gzyx2gtcn, child number 0
-------------------------------------
select *  from   dual where  to_date(sysdate) < sysdate

Plan hash value: 3752461848

----------------------------------------------------------------------------
| Id  | Operation          | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time   |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |        |       |     2 (100)|          |
|*  1 |  FILTER            |      |        |       |            |          |
|   2 |   TABLE ACCESS FULL| DUAL |      1 |     2 |     2   (0)| 00:00:01 |
----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter(TO_DATE(TO_CHAR(SYSDATE@!))<SYSDATE@!)

Вы можете ясно видеть TO_CHAR() в состоянии фильтра.

5

Другие решения

Ошибка здесь:

to_date (sysdate, ‘MM-YYYY’)

Посмотрим почему:

SQL> select to_date(sysdate, 'MM-YYYY') from dual;
select to_date(sysdate, 'MM-YYYY') from dual
*
ERROR at line 1:
ORA-01843: not a valid monthSQL>

Вам не нужно снова конвертировать sysdate в дату. Удалить to_date и просто использовать SYSDATE.

НОТА В качестве дополнительной информации, пожалуйста, посмотрите на @ Boneist’s ответ для понимания относительно неявного преобразования, которое Oracle вынужден делать при применении на свидание на SYSDATE,

Вы используете to_date, чтобы преобразовать строку в дату. Для расчета даты вам просто нужно использовать значение даты.

Например,

SQL> WITH DATA AS(
2  SELECT '20150101' cal_wid FROM DUAL
3  )
4  SELECT *
5  FROM DATA
6  WHERE   to_date(cal_wid,'yyyymmdd')
7  BETWEEN add_months(SYSDATE,-12)
8  AND     SYSDATE
9  /

CAL_WID
--------
20150101

SQL>

Измените ваш запрос как:

WHERE to_date(cal_wid,'yyyymmdd') BETWEEN add_months(SYSDATE, -12) AND SYSDATE
1

По вопросам рекламы [email protected]