Oracle ORA-01722: 由于 WHERE IS NULL 条件导致的无效数字错误
Posted
技术标签:
【中文标题】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: 由于 WHERE IS NULL 条件导致的无效数字错误的主要内容,如果未能解决你的问题,请参考以下文章
Oracle SQL:插入失败 ORA-01722:无效数字,数据是数字而不是字符串,为啥会失败?