使用add_months时,oracle中的有效月份不是

rji*_*rji 2 php sql oracle to-date sysdate

我在查询中给出了以下代码.

    where to_date(cal_wid,'yyyymmdd') 
    between  add_months(to_date(sysdate, 'MM-YYYY'),-12) 
    and      to_date(sysdate, 'MM-YYYY')
Run Code Online (Sandbox Code Playgroud)

我收到以下错误.(我在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
Run Code Online (Sandbox Code Playgroud)

任何人都可以告诉我为什么会收到此错误?

Bon*_*ist 5

永远不要使用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的证明,如果你按照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@!)
Run Code Online (Sandbox Code Playgroud)

您可以清楚地看到TO_CHAR()过滤条件.