Oracle SQL替换不同位置的多个字符

时间:2017-08-24 12:59:16

标签: sql oracle

我使用的是Oracle 11g,而且我在根据不同表格中提到的位置替换多个字符时遇到了问题。例如:

表1

PRSKEY POSITION CHARACTER
  123     3         ć
  123     9         ć

表2

PRSKEY   NAME 
  123   Becirovic

我必须将表2 中的NAME替换为Bećirović。 我已尝试regexp_replace,但此功能无法提供超过1个位置,是否有一种简单的方法可以解决此问题?

3 个答案:

答案 0 :(得分:1)

这是另一种方法。

with tab1 as (select 123 as prskey, 3 as position, 'ć' as character from dual
            union select 123, 9, 'ć' from dual),
     tab2 as (select 123 as prskey, 'Becirovic' as name from dual)
select listagg(nvl(tab1.character, namechar)) within group(order by lvl) 
from
  (select prskey, substr(name, level, 1) as namechar, level as lvl
    from tab2
    connect by level <= length(name)
  ) splitname
left join tab1 on position = lvl and tab1.prskey = splitname.prskey
;

答案 1 :(得分:0)

我更喜欢通过PL / SQL进行处理,但是在你的标签中只有'sql',所以我做了这个怪物:

with t as (
  select 123 as id, 3 as pos, 'q' as new_char from dual
  union all
  select 123 as id, 6 as pos, 'z' as new_char from dual
  union all
  select 123 as id, 9 as pos, '1' as new_char from dual
  union all
  select 456 as id, 1 as pos, 'A' as new_char from dual
  union all
  select 456 as id, 4 as pos, 'Z' as new_char from dual
),
t1 as (
  select 123 as id, 'Becirovic' as str from dual
  union all
  select 456 as id, 'Test' as str from dual
)                    
select listagg(out_text) within group (order by pos) 
from( 
  select id, pos, new_char, str, prev, substr(str,prev,pos-prev)||new_char as out_text
  from(
    select id, pos, new_char, str, nvl(lag(pos) over (partition by id order by pos)+1,1)  as prev
    from (
      select t.id, pos, new_char, str
      from t, t1
      where t.id = t1.id
    ) q
  ) a
) w
group by id

结果:

Beqirzvi1
AesZ

答案 2 :(得分:0)

使用光标的简单解决方案......

create table t1 (
  prskey int,
  pos int,
  character char(1)
);

create table t2
(
  prskey int,
  name varchar2(100)
);

insert into t1 values (1, 1, 'b');
insert into t1 values (1, 3, 'e');

insert into t2 values (1, 'dear');


begin
  for t1rec in (select * from t1) loop    
    update t2
    set name = substr(name, 1, t1rec.pos - 1) || t1rec.character || substr(name, t1rec.pos + 1, length(name) - t1rec.pos)
    where t2.prskey = t1rec.prskey;
  end loop;
end;
/