oracle ORA-01722连接表时出现无效编号错误

bqujaahr  于 2023-03-29  发布在  Oracle
关注(0)|答案(1)|浏览(142)

连接表时出错:

with cte1 as
( 
    select 
        p.*, 
        cast(regexp_replace(p.phone_number, '\+|\(|\)\ ', '') as varchar2(50)) as phone
    from 
        PHONE_TABLE p
    where 
        t.phone_number is not null 
    order by 
        p.phone_number asc
)
select * 
from cte1 t1
join PHONE_TABLE1 t on t.phone = t1.phone

我尝试使用转换功能

7vux5j2d

7vux5j2d1#

您似乎希望在从phone_number中删除+()字符后,分别在phone_number(字符串)和phone(数字)列上连接表PHONE_TABLEPHONE_TABLE1
你可以使用TRANSLATE函数(避免缓慢的正则表达式):

with cte1 as
( 
  select p.*, 
         TRANSLATE(p.phone_number, '0+() ', '0') as phone
  from   PHONE_TABLE p
  where  p.phone_number is not null 
  order by 
         p.phone_number asc
)
select * 
from   cte1 t1
       join PHONE_TABLE1 t on t.phone = t1.phone

或者,更简单地说,没有CTE:

select p.*,
       TRANSLATE(p.phone_number, '0+() ', '0') AS phone,
       p1.*
from   phone_table p
       join PHONE_TABLE1 p1
       on TRANSLATE(p.phone_number, '0+() ', '0') = p1.phone
order by 
       p.phone_number asc;

其中,对于示例数据:

CREATE TABLE phone_table (
  id NUMBER,
  phone_number VARCHAR2(50)
);

CREATE TABLE phone_table1 (
  id NUMBER,
  phone NUMBER
);

INSERT INTO phone_table (id, phone_number)
  SELECT 1, '+1(23) 456' FROM DUAL UNION ALL
  SELECT 2, '123456' FROM DUAL UNION ALL
  SELECT 3, '987654' FROM DUAL;

INSERT INTO phone_table1 (id, phone)
  SELECT 101, 123456 FROM DUAL UNION ALL
  SELECT 102, 987654 FROM DUAL;

输出:
| ID|电话号码|联系电话|ID|联系电话|
| --------------|--------------|--------------|--------------|--------------|
| 1|电话:+1(23)456|小行星123456|一百零一|小行星123456|
| 二|小行星123456|小行星123456|一百零一|小行星123456|
| 三|九八七六五四|九八七六五四|一百零二|九八七六五四|
如果你在PHONE_TABLE中有一个字符串,在删除这些字符后,它将不是一个有效的数字:

INSERT INTO phone_table (id, phone_number) VALUES (4, '987-654');

然后上面的操作会失败,因为在JOIN中从字符串到数字的隐式转换会失败。你可以通过显式比较字符串来解决这个问题:

select p.*,
       TRANSLATE(p.phone_number, '0+() ', '0') AS phone,
       p1.*
from   phone_table p
       join PHONE_TABLE1 p1
       on TRANSLATE(p.phone_number, '0+() ', '0') = TO_CHAR(p1.phone)
order by 
       p.phone_number asc

或者,在Oracle 12中,将字符串显式转换为数字,并使用DEFAULT NULL ON CONVERSION ERROR选项:

select p.*,
       TRANSLATE(p.phone_number, '0+() ', '0') AS phone,
       p1.*
from   phone_table p
       join PHONE_TABLE1 p1
       on TO_NUMBER(
            TRANSLATE(p.phone_number, '0+() ', '0')
            DEFAULT NULL ON CONVERSION ERROR
          ) = p1.phone
order by 
       p.phone_number asc

其输出相同。
fiddle

相关问题