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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了什么是“oracle ORA-01722”无效数字?相关的知识,希望对你有一定的参考价值。

参考技术A

    对于两个类型不匹配(一个数字类型,一个非数字类型,同下)的值进行赋值操作;

    两个类型不匹配的值进行比较操作(例如,“=”);

    to_number函数中的值,非数字的,比如,to_number('a')肯定是不行的,

    to_number('12306')则是正常的。

    要避免这些问题,要做到在写sql语句时就好认真处理好不同类型的问题。

    比如如果要比较的话,同时都用to_number强制转换(to_number(字段a) = to_number(字段b)。

    或者同时转换为字符串类型。

    在语句中使用to_number函数时,要保证值一定是数字格式,或者写好异常处理。

    当我们碰到这个错误提示时,就从所有用到的数字类型的字段开始检查,逐一排查,从而解决问题。

参考技术B

    “oracle ORA-01722”是字段中存在非数字的字符。

    主要原因是:

    (1)对于两个类型不匹配(一个数字类型,一个非数字类型,同下)的值进行赋值操作;

    (2)两个类型不匹配的值进行比较操作(例如,“=”);

    (3)to_number函数中的值,非数字的,比如,to_number('a')肯定是不行的,to_number('12306')则是正常的。

原因分析如下: 

    显式原因:即字段中存在非数字的字符。

    解决方法:、

    (1)替换掉非数字的字符。

    (2)使用 ORACLE的regexp_like函数,过滤掉含有非数字字符的记录。

    隐式原因:

    就是对某个字段进行使用一些函数后,字段的类型已经转换成了VARCHAR2类型,VARCHAR2存在着全角和半角符号之分。当这个字段是全角字符时,即使你看到该字段是纯数字,但是在where子句中使用to_number,却提示ORA-01722异常。

    解决方法:

    在select语句中对该字段进行to_number转换,然后在嵌套一个查询语句,在where子句中to_number(字段),即可。

参考技术C

    存储过程的目的是,实现当在数据库中插入一条记录的时候,将汽车编号的数据库代码转换为实际的汽车的名称。

    汽车表:包括ID,NUMBER(2)和NAME(VARCHAR2(8))字段,实现将实际的车号和数据库处理的车号的对应。

    汽车称重表:包括序号HEATID(VARCHAR2)、时间CHAREGE_TIME(DATE)、实际车号CRANEID(VARCHAR2(8))。

    触发器:实现实际车号和数据库系统车号转换功能。

2.打开汽车车辆表,输入按照序号条件进行查询的SQL语句,如下图。鼠标左键选中记录行1左边的黑色箭头,使用Ctrl+C进行复制操作,将该条数据复制到粘贴板。

3.鼠标左键选中小HEATID上边的小锁子,打开编辑功能,使用粘贴功能进行粘贴,刚才选中的数据被粘贴到数据表的第二行中,修改HEATID汽车编号为160700000。

4.鼠标左键选中小勾,然后按F1执行,系统报错。报错界面显示“ORA-01722:无效数字”报错,点击Yes按钮,跳转到触发器编辑调试界面。

5.查看触发器界面,红色字体黄色背景的语句为错误所在部位。由于程序报无效数字,重点关注表中字段数据类型,程序中涉及到从车辆表crane_ID读取name数据,复制给craneid,重点关注craneid,检查发现craneid的数据类型为CRANEID(VARCHAR2(8)),我们在数据库中的数值为“7”,为number类型,数据类型不一致,问题所在找到了。怎么解决呢?下一步进行操作解决。

6.根据汽车表数据对应关系,将ceaneid字段的7,按照对应关系,修改为26#,点击小锁子进行编辑,按F8执行,数据成功插入,触发器没有报错,问题解决。

Oracle ORA-01722: 由于 WHERE IS NULL 条件导致的无效数字错误

【中文标题】Oracle ORA-01722: 由于 WHERE IS NULL 条件导致的无效数字错误【英文标题】:Oracle ORA-01722: invalid number Error because of WHERE IS NULL Condition 【发布时间】:2018-07-10 16:19:12 【问题描述】:

我有以下 SQL:

Select MyNumber
FROM (SELECT to_number(Name) AS MyNumber
    FROM TableA
    WHERE regexp_replace(Name, '\d+') IS NULL)

查询应该从 TableA 中过滤掉非数字名称,方法是检查是否没有剩余,如果所有数字都被替换为空。

当我将以下 WHERE 条件添加为外部 WHERE 时,有人可以解释为什么我得到一个“无效号码”异常:

WHERE MyNumber IS NULL

它是如何相关的,MyNumber 是什么类型?特别是,我还想知道,当我否定条件时,为什么我没有收到错误:

WHERE NOT MyNumber IS NULL

提前感谢您的帮助。

【问题讨论】:

如果您使用的是 Oracle 12cR2,那么 DEFAULT ...ON CONVERSION ERROR 就像 here 所以第一个查询运行得很好? (to_number() 不会出错)。 只是一个提示,你可能宁愿使用REGEXP_LIKE,而不是使用REGEXP_REPLACE 【参考方案1】:

我可以复制您所看到的内容,但我收到is null 的错误 is not null

create table tablea (name) as
select '123' from dual
union all select 'abc123' from dual
union all select 'abc123def456,' from dual
union all select '1abc123def456,' from dual;

SELECT MyNumber
FROM (
  SELECT to_number(Name) AS MyNumber
  FROM TableA
  WHERE regexp_replace(Name, '\d+') IS NULL
);

  MYNUMBER
----------
       123

SELECT MyNumber
FROM (
  SELECT to_number(Name) AS MyNumber
  FROM TableA
  WHERE regexp_replace(Name, '\d+') IS NULL
)
WHERE mynumber IS NULL;

ORA-01722: invalid number

SELECT MyNumber
FROM (
  SELECT to_number(Name) AS MyNumber
  FROM TableA
  WHERE regexp_replace(Name, '\d+') IS NULL
)
WHERE mynumber IS NOT NULL;

ORA-01722: invalid number

您也许可以添加提示以使其以不同方式处理它,但您可以添加另一个正则表达式,这样任何非数字值都不会导致转换:

SELECT MyNumber
FROM (
  SELECT to_number(regexp_replace(Name, '[^[:digit:]]')) AS MyNumber
  FROM TableA
  WHERE regexp_replace(Name, '[[:digit:]]+') IS NULL
);

  MYNUMBER
----------
       123

SELECT MyNumber
FROM (
  SELECT to_number(regexp_replace(Name, '[^[:digit:]]')) AS MyNumber
  FROM TableA
  WHERE regexp_replace(Name, '[[:digit:]]+') IS NULL
)
WHERE mynumber IS NULL;

no rows selected

SELECT MyNumber
FROM (
  SELECT to_number(regexp_replace(Name, '[^[:digit:]]')) AS MyNumber
  FROM TableA
  WHERE regexp_replace(Name, '[[:digit:]]+') IS NULL
)
WHERE mynumber IS NOT NULL;

  MYNUMBER
----------
       123

正如@MrLlama 指出的那样,使用regexp_like 会更简洁:

SELECT MyNumber
FROM (
  SELECT to_number(regexp_replace(Name, '[^[:digit:]]')) AS MyNumber
  FROM TableA
  WHERE regexp_like(Name, '^[[:digit:]]+$')
);

得到相同的结果(包括你原来的错误)。

【讨论】:

【参考方案2】:

查询应该从 TableA 中过滤掉非数字名称

你为什么不使用这样的东西呢?

SQL> with test (name) as
  2    (select '12345'     from dual union
  3     select 'abc123'    from dual union
  4     select 'lksfj'     from dual union
  5     select 'ping pong' from dual
  6    )
  7  select name
  8  from test
  9  where regexp_like(name, '^\d+$');

NAME
---------
12345

SQL>

这可能需要一些调整,具体取决于 NAME 列实际包含的内容。

【讨论】:

以上是关于什么是“oracle ORA-01722”无效数字?的主要内容,如果未能解决你的问题,请参考以下文章

如何修复 oracle ORA-01722 无效号码错误

调用 Java 过程时 Oracle ORA-01722

Oracle SQL:插入失败 ORA-01722:无效数字,数据是数字而不是字符串,为啥会失败?

ORA-01481: 无效的数字格式模型

解析错误:无效的数字文字

oracle算时间差 为什么老提示我 无效数字呢 语句如下