2017-08-24 12 views
2

Oracle 11gを使用していますが、別の表に記載されている位置に基づいて複数の文字を置き換える際に問題があります。たとえば:Oracle SQL異なる位置に複数の文字を置き換えます。

表1

PRSKEY POSITION CHARACTER 
    123  3   ć 
    123  9   ć 

表2

PRSKEY NAME 
    123 Becirovic 

私はNAME 2表Bećirovićにを交換する必要があります。 私はregexp_replaceを試しましたが、この機能は1位以上を置き換えるものではありませんが、これを簡単に修正する方法はありますか?

+0

私はあなたが適用されるすべての置換ルールを単一のレコードにあなたの文字列を取得する必要があると思い、これを行うのいずれかのチャンスがあると思う(中2上のあなたの例)。私はこれを行う方法が表示されません。この問題がどのようにして終わったのか聞いてもらえますか? –

+0

私は最良の方法は機能だろうと思う。環境内で関数を作成できますか? – pOrinG

+0

@TimBiegeleisenテーブルに参加し、 'group by'を追加し、' LISTAGG() '関数を追加します(MySQLの場合はGROUP_CONCATです)。グループメンバーを注文し、複数の部分を持つように文字列をカットする必要があります。うまくいくはずですが、クエリは難しいでしょう。簡単に関数を導入できます。 – StanislavL

答えて

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; 
/
+0

サンクスは、完璧に動作します! – Erwin

+0

@Erwinあなたは大歓迎です:)私はビールを持っています –

+0

私は@Radim Bacaをしました;-)。簡単な質問:このカーソルをストアドプロシージャにラップする方法はありますか? – Erwin

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 
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 
; 
+0

本当に素晴らしいsollution –

関連する問題