什么是“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函数时,要保证值一定是数字格式,或者写好异常处理。
当我们碰到这个错误提示时,就从所有用到的数字类型的字段开始检查,逐一排查,从而解决问题。
“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(字段),即可。
存储过程的目的是,实现当在数据库中插入一条记录的时候,将汽车编号的数据库代码转换为实际的汽车的名称。
汽车表:包括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”无效数字?的主要内容,如果未能解决你的问题,请参考以下文章