Oracle ORA-01722:无效的数字错误,因为WHERE IS NULL条件

时间:2018-07-10 16:19:13

标签: sql oracle isnull

我有以下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

在此先感谢您的帮助。

2 个答案:

答案 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列的内容。