【问题标题】:oracle join string to number not working by adding regexp_likeoracle通过添加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。

标签: sql oracle join


【解决方案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 过滤器会避免数据类型转换错误。它应该总是在访问谓词之前评估过滤谓词吗?在某些情况下,这会导致性能下降。
猜你喜欢
  • 1970-01-01
  • 2020-01-12
  • 2016-09-23
  • 1970-01-01
  • 2017-05-16
  • 1970-01-01
  • 1970-01-01
  • 2021-01-26
  • 1970-01-01
相关资源
最近更新 更多