我有以下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
在此先感谢您的帮助。
答案 0 :(得分:2)
我可以复制您所看到的内容,但是出现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:]]+$')
);
获得相同的结果(包括原始错误)。
答案 1 :(得分:0)
查询应该从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
列的内容。