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:无效数字,数据是数字而不是字符串,为啥会失败?

讨厌麻烦的ora 01722无效数字

Codeigniter 中的 Oracle 查询给出 ORA-01722 和 ORA-01756

调用 Java 过程时 Oracle ORA-01722

Oracle报错ORA-01722: 无效数字排查解决方案

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