首页 > 解决方案 > 具有转换功能的日期在 oracle 中给出错误

问题描述

当我执行以下查询时

SELECT (TO_NUMBER (TO_CHAR ('25-07-19', 'YYYY')) - 1) + CEIL
(
  CASE
  WHEN (MONTHS_BETWEEN ( LAST_DAY ( TO_DATE ( TO_CHAR ('18-05-2020', 'DD/MM/YYYY'), 'DD-MM-YYYY')), LAST_DAY ('25-07-19')))>0 THEN
  MONTHS_BETWEEN ( LAST_DAY ( TO_DATE ( TO_CHAR ('18-05-2020', 'DD/MM/YYYY'), 'DD-MM-YYYY')), LAST_DAY ('25-07-19'))
  ELSE 1 END / 12) Year 
  FROM dual;

收到如下返回错误

ORA-01722: invalid number
01722. 00000 -  "invalid number"
*Cause:    The specified number was invalid.
*Action:   Specify a valid number.

标签: sqloracle

解决方案


您的错误来自调用TO_CHAR,例如:

TO_CHAR ('25-07-19', 'YYYY')

或者

TO_CHAR ('18-05-2020', 'DD/MM/YYYY')

函数重载,第TO_CHAR一个参数可以是数字或日期;您没有提供任何内容并传入了一个字符串,因此 Oracle 正在尝试隐式转换'25-07-19''18-05-2020'为数字,因为它不知道您希望它是一个日期。您不应该依赖隐式转换。

相反,您可以将字符串显式转换为日期:

TO_CHAR ( TO_DATE( '18-05-2020', 'DD-MM-YYYY' ), 'DD/MM/YYYY')

但是,最好使用日期文字DATE '2020-05-18',或者,如果您要立即将其再次转换为字符串,则只需提供正确格式的字符串。

TO_CHAR因此,您可以通过消除调用并将大多数TO_DATE调用替换为日期文字来大大简化您的功能。同样,您不需要使用TO_NUMBER( TO_CHAR( date_value, 'YYYY' ) ),而是可以使用EXTRACT. 您也可以将您的CASE语句替换为GREATEST.

这使您可以进行更简单的查询:

SELECT EXTRACT( YEAR FROM DATE '2019-07-25' )
       - 1
       + CEIL(
           GREATEST(
             MONTHS_BETWEEN(
               LAST_DAY( DATE '2020-05-18' ),
               LAST_DAY( DATE '2019-07-25' )
             ),
             1
           ) / 12
         ) AS Year
FROM   DUAL;

哪个输出:

| 年份 |
| ---: |
| 2019 |

db<>在这里摆弄


推荐阅读