永远不要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”,这很可能是您设置的值。
如果您只想将_months 添加到当月的第一天,那么您应该使用TRUNC()
,例如:
add_months(trunc(sysdate, 'MM'),-12)
这是隐式 to_char 的证明,如果您按照 Lalit 的要求对已经是日期的内容进行 to_date - 涉及 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()
过滤条件中的 。