ORA-01722: 使用 to_number 时号码无效

Posted

技术标签:

【中文标题】ORA-01722: 使用 to_number 时号码无效【英文标题】:ORA-01722: invalid number when using to_number 【发布时间】:2019-08-23 14:24:08 【问题描述】:

我正在尝试使用项目代码和这样的客户代码在表中查找最大项目代码

SELECT DISTINCT       Max(to_number(translate(substr(proj_code,7),'0123456789','0123456789')))
    FROM
        proj_ca
    WHERE
        proj_code LIKE 'CUST43_%'
        AND cust_code = 'CUST';

此代码应该返回 97 当我运行此代码时,我得到 ORA-01722 无效数字,但是当我执行 42 或 44 时,它返回正确的数字。我不确定为什么“to_number”会引发错误。

我已将范围缩小到“to_number”部分。如果我删除它,它会返回 97 而没有任何问题。

【问题讨论】:

您是否有 CUST4397 行,代码为 CUST 和其他内容;但是您可以成功获得的其他人只有有 CUST?或者其他以CUST4397 开头但在它之前排序的东西——即没有最大值你会看到什么? translate 应该做什么?你写它的方式,它绝对没有任何作用。我想你认为它做了一些事情,也许这就是问题(或一个问题,无论如何)。 您使用的是哪个版本的 Oracle?我问是因为在 12.2 中,to_number has been extended 所以它可以更好地处理转换错误。 @AlexPoole 所有项目代码后面都有数字。所以所有的行都包含 CUSTXXXX。如果没有 max,它会返回所有包含 CUST43XX 的行。 @mathguy 我没有写代码。你能解释为什么它什么都不做吗? 【参考方案1】:

Oracle 的TRANSLATE 函数不会对输入字符串中的字符执行任何操作,但不会对要转换的字符列表中的字符执行任何操作。所以这个:

select translate(substr('CUST4397B',7),'0123456789','0123456789') 
from dual;

将返回“97B”,而不是“97”。

尝试将其放入您的代码中:

select regexp_replace(substr('CUST4397B',7),'[^0-9]','')  answer
from dual;
answer
------
97

【讨论】:

下划线是like中的单个通配符;所以我没有看到(从问题文本中,它指的是它返回 97 否则)有一个文字下划线要处理?不过有点迷茫…… @AlexPoole 你是对的,当然。我很快把它当作字面下划线来读,因为如果不是,我会期待 `LIKE 'CUST43%'。也许她是想确保在 43 之后至少有一个职位。我会更新我的答案。 我没有写那个代码,所以我假设@MatthewMcPeak 你的理论在这个位置上是正确的。此代码会将字符串转换为数字吗?还是需要加select max(to_number(regexp_replace(substr('CUST4397B',7),'[^0-9]',''))) 是的,您仍然需要max(to_number(..))。祝你好运! 感谢马修这工作!浏览列表有一个项目代码,末尾带有“A”。然而,在那之后已经做了很多项目,所以我确信这不是问题。猜猜它毕竟是。非常感谢!【参考方案2】:

一种稍微不同的方法,我认为更灵活一点是使用

SELECT MAX(TO_NUMBER(REGEXP_SUBSTR(PROJ_CODE, '[0-9]2', 1, 2)))
  FROM PROJ_CA
  WHERE PROJ_CODE LIKE 'CUST43%' AND
        CUST_CODE = 'CUST'

这里数字在字符串中的位置不是硬编码的——而是提取字符串中找到的第二组两位数字,CUST4397B 的情况是97

dbfiddle here

【讨论】:

我喜欢它。但是这个版本将一个假设(从第 7 个位置开始)与另一个假设(项目编号始终为 2 个位置)进行了交换。如果我们要获得最大的灵活性,REGEXP_SUBSTR(proj_code, '43([0-9]+)', 1, 1, 'i', 1) 怎么样? 在评论中 OP 说“......所有项目代码后面都有数字。所以所有行都包含 CUSTXXXX......”。但是,在我的辩护中,这仍然适用于 VENDORXXXX 或 COWHERDERXXXX 或 WHATINHECKISTHISSUPPOSEDTOBEXXXX 等项目编号。【参考方案3】:

假设输入是 CUST43_42 translate 将返回输出为 '_42' 不能转换为数字,因此 to_number 会抛出无效数字。 试试 SUBSTR (proj_code, 8)

【讨论】:

输入始终是客户代码和后面的两个数字,因此始终是 CUSTXX。那有意义吗?但是我确实尝试了您的建议并得到了同样的错误 你可以分享一个示例数据

以上是关于ORA-01722: 使用 to_number 时号码无效的主要内容,如果未能解决你的问题,请参考以下文章

什么是“oracle ORA-01722”无效数字?

ORACLE-023:令人烦恼的 ora-01722 无效数字

AVG 中的 TO_NUMBER 函数不起作用

ORA-01722 运行存储过程时出错

调用 Java 过程时 Oracle ORA-01722

SQL ORA-01722: 无效号码