【问题标题】:Inconsistent error ORA-01722: invalid number不一致的错误 ORA-01722: 无效号码
【发布时间】:2018-05-15 11:03:33
【问题描述】:

我在执行查询时收到错误消息“ORA-01722:无效号码”。深入研究后,我发现,当我将数值用于需要varchar 的列时,我会收到该错误。 就我而言,我的查询有一个类似

的 case 语句
CASE WHEN CHAR_COLUMN= 1 THEN 'SOME VALUE' END

但是在同一 oracle 版本的不同实例中行为是不同的。相同的查询在我们的一个开发 oracle 服务器中有效,但在另一个中无效。我很好奇是否有任何配置允许 oracle 在字符列中使用数值。

PS:我们使用的 oracle 版本是 Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production

【问题讨论】:

  • 可能两台服务器的数据不同,而您的开发服务器没有任何非数字字符串的行?

标签: oracle


【解决方案1】:

我从不依赖implicit data type conversion,但总是明确表示:

CASE WHEN CHAR_COLUMN = TO_CHAR(1) THEN 'SOME VALUE' END

甚至根本不转换:

CASE WHEN CHAR_COLUMN = '1' THEN 'SOME VALUE' END

原因是Oracle倾向于将字符串转换为数字,而不是相反。请参阅链接手册页中的示例:

文本文字示例

文本文字“10”的数据类型为 CHAR。如果它出现在如下语句中的数值表达式中,Oracle 会将其隐式转换为 NUMBER 数据类型:

SELECT salary + '10'
  FROM employees;

【讨论】:

    【解决方案2】:

    致reproduce the issue:

    create table foo (
      CHAR_COLUMN varchar2(10)
    );
    create table bar (
      CHAR_COLUMN varchar2(10)
    );
    insert into foo (CHAR_COLUMN) values ('1');
    insert into foo (CHAR_COLUMN) values ('2');
    insert into bar (CHAR_COLUMN) values ('1');
    insert into bar (CHAR_COLUMN) values ('yellow');
    

    然后,当查询数字 1 时,第一个查询表有效,而第二个查询表无效:

    select * from foo where CHAR_COLUMN = 1;
    select * from bar where CHAR_COLUMN = 1;
    

    当您要求 Oracle 解决此比较时:

    WHEN CHAR_COLUMN = 1
    

    ...Oracle 在内部将查询转换为:

    WHEN TO_NUMBER(CHAR_COLUMN) = 1
    

    在我的示例中,这可以在解释计划中发现:

    ---------------------------------------------------------------------
    | Id  | Operation           | Name | Rows | Bytes | Cost | Time     |
    ---------------------------------------------------------------------
    |   0 | SELECT STATEMENT    |      |    1 |     7 |    3 | 00:00:01 |
    | * 1 |   TABLE ACCESS FULL | FOO  |    1 |     7 |    3 | 00:00:01 |
    ---------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ------------------------------------------
    * 1 - filter(TO_NUMBER("CHAR_COLUMN")=1)
    

    【讨论】:

      猜你喜欢
      • 2018-02-14
      • 2012-09-14
      • 1970-01-01
      • 2019-08-09
      • 2021-05-03
      • 2023-03-15
      • 2020-05-09
      相关资源
      最近更新 更多