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.