oracle通过添加regexp_like将字符串连接到数字不起作用

Posted

技术标签:

【中文标题】oracle通过添加regexp_like将字符串连接到数字不起作用【英文标题】:oracle join string to number not working by adding regexp_like 【发布时间】:2019-11-02 22:12:39 【问题描述】:

oracle 通过添加 regexp_like 将字符串连接到数字不起作用。例如,

Foo                           Bar
--------------                ------------
id varchar2(20)               id number(20,0)

Foo id 可以是数字或任何字符串(不是数字),例如 123、hello、world、555 等。

select foo.id,bar.id from Foo foo 
left join Bar bar on (regexp_like(foo.id, '^[0-9]+$') and foo.id=bar.id)

错误:

ERROR at line 1:
ORA-01722: invalid number

foo.id=bar.id 仅在 foo.id 是数字时才被评估,对吧?

以下对 mysql 工作正常

select foo.id,bar.id from Foo foo 
left join Bar bar on (foo.id=bar.id)

但它会导致 ORA-01722: invalid number for oracle。这就是连接条件中添加“regexp_like”的原因。

【问题讨论】:

嗨@Sunnyday 为什么Oracle数据库标签和这个“以下对mysql工作正常”?谢谢! 我知道。我希望mysql版本适用于oracle。 【参考方案1】:

类似这样的:

select foo.id
       , bar.id 
from Foo foo 
left join Bar bar on foo.id = to_char(bar.id);

这里是DEMO

【讨论】:

@Sunnyday 这是你需要的吗?还是? 正在将数字转换为字符。但是你知道为什么添加 regexp_like 不起作用吗? 好的,我会检查的,但这不是问题。我为此提出新问题。我也相信这个答案应该被标记为正确。我会尝试找出为什么 regexp_like 不起作用... 请您从这个演示中解释一下:dbfiddle.uk/… 为什么 regexp_like 不起作用?谢谢! 左连接。不同的结果。【参考方案2】:

需要 Oracle 12.2 或更高版本:

select foo.id,bar.id
from   foo
       left join bar on bar.id = to_number(foo.id default 0 on conversion error);

(我希望它可以与 default null on conversion error 一起使用,但它会使会话崩溃。)

关于您关于为什么使用 regexp_like 的原始尝试不起作用的问题,它在 12.2.0.1 中对我有用。可能在您的情况下,它首先评估foo.id = bar.id。可以提示或重写查询以强制首先应用正则表达式。

【讨论】:

如果 (foo.id=bar.id) 首先被评估,这是一个错误。但是oracle有很多用户,应该不是bug。我正在测试 Oracle 11g。 为什么是错误?优化器无法知道regex_like 过滤器会避免数据类型转换错误。它应该总是在访问谓词之前评估过滤谓词吗?在某些情况下,这会导致性能下降。

以上是关于oracle通过添加regexp_like将字符串连接到数字不起作用的主要内容,如果未能解决你的问题,请参考以下文章

ORACLE:如何使用 regexp_like 查找两个字符之间带有单引号的字符串?

Oracle正则表达式之 Regexp_substr,Regexp_instr,Regexp_replace,Regexp_like

Oracle regexp_like - 只有某些字符、数字和一个符号

Oracle 正则表达式函数-REGEXP_LIKE 使用例子

Oracle SQL - REGEXP_LIKE 包含字符串“NA”以外的字符

Oracle SQL - REGEXP_LIKE 在 CHECK 约束中没有按预期工作