Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Não é um mês válido no oracle quando add_months é usado


Nunca, nunca use TO_DATE() em algo que já é um DATE . A razão para isso é porque a Oracle terá que fazer algumas conversões implícitas para seguir seus desejos:

TO_DATE(sysdate, 'mm-yyyy')

é realmente executado como

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

então se o seu nls_date_format estiver definido para algo diferente de 'mm-yyyy', você terá problemas. O parâmetro nls_date_format padrão é 'DD-MON-YY', que é mais do que provável o valor para o qual o seu está definido.

Se tudo o que você queria fazer era adicionar_meses ao primeiro dia do mês atual, então você deveria usar TRUNC() , por exemplo:

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

Aqui está a prova do to_char implícito se você to_date algo que já é uma data, conforme solicitado por Lalit - um plano de execução de uma consulta básica envolvendo 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([email protected]!))<[email protected]!)

Você pode ver claramente o TO_CHAR() na condição de filtro.