2008-09-17 12 views
9

「{3}で支払う{2}お支払いができません{1}」のような表から文字列があります。私は{1}をある値で置き換えたい、{2}をある値で置き換え、{3}をある値で置き換えたい。複数の文字列をOracle内で一緒に置き換える方法

3つすべてを1つの置換関数に置き換えることは可能ですか?または私は直接クエリを記述し、値を置き換えることができます何らかの方法はありますか?私はOracleのストアドプロシージャでこれらの文字列を置き換える元の文字列が私のテーブルの1つから来ている私はちょうどそのテーブルで選択しています

その後、{1}、{2}、{3}の値その文字列から、私が持っている他の値を別のテーブルから

+0

可能性のある重複した[より大きくならないことを仮定しているの下にfunction in Oracle](https://stackoverflow.com/questions/2947623/multiple-replace-function-in-oracle) – Joaquinglezsantos

答えて

12

それは1回のコールではありませんが、あなたは巣replace()通話することができます:

SET mycol = replace(replace(mycol, '{1}', 'myoneval'), '{2}', mytwoval) 
+0

2番目のmytwovalには一重引用符がありませんか? –

+0

@SimonTheCatあなたは正しいです! (mytwovalが変数でない限り) – hamishmcn

-1

あなたは選択のこの内部を行っている場合は、することができます文字列の連結を使用して、置換値が列の場合は、それをまとめてください。

4

置き換える変数が多数あり、それらを別のテーブルに入れておき、変数の数が可変であれば、それらを置き換えるために再帰的なCTEを使用できます。 以下の例。テーブルfg_rulezでは、文字列を置き換えて置きます。テーブルfg_dataに入力文字列があります。

set define off; 
drop table fg_rulez 
create table fg_rulez as 
    select 1 id,'<' symbol, 'less than' text from dual 
    union all select 2, '>', 'great than' from dual 
    union all select 3, '$', 'dollars' from dual 
    union all select 4, '&', 'and' from dual; 
drop table fg_data; 
create table fg_Data AS(
    SELECT 'amount $ must be < 1 & > 2' str FROM dual 
    union all 
    SELECT 'John is > Peter & has many $' str FROM dual 
    union all 
    SELECT 'Eliana is < mary & do not has many $' str FROM dual 

    ); 


WITH q(str, id) as (
    SELECT str, 0 id 
    FROM fg_Data 
    UNION ALL 
    SELECT replace(q.str,symbol,text), fg_rulez.id 
    FROM q 
    JOIN fg_rulez 
    ON q.id = fg_rulez.id - 1 
) 
SELECT str from q where id = (select max(id) from fg_rulez); 

したがって、単一のreplaceです。

結果:交換する値の数が大きすぎるか、あなたができるようにする必要がある場合

amount dollars must be less than 1 and great than 2 
John is great than Peter and has many dollars 
Eliana is less than mary and do not has many dollars 

代わりに変数の用語シンボルがthis duplicated question.

のOracle 11gR2の

+0

WITH句のエイリアシングは、Oracle 11gR2以降でサポートされています。 – Stephan

+1

IMHこれは、悲しいことに、悲しいことに、質問でのみ参照された点、つまり実際のクエリを編集することなく置換された用語を更新できるようにするための優れた答えです(制御された環境では有用なシナリオです)。 – Neil

1

から来ています簡単にそれを維持するために、あなたはまた、文字列を分割し、辞書テーブルを使用して、最終的に結果を集計することができます

例では

は、私はあなたの文字列内の単語をblankspacesで分離され、複数のREPLACE文字列内の語数は100(ピボットテーブルカーディナリティ)の

with Dict as 
(select '{1}' String, 'myfirstval' Repl from dual 
    union all 
    select '{2}' String, 'mysecondval' Repl from dual 
    union all 
    select '{3}' String, 'mythirdval' Repl from dual 
    union all 
    select '{Nth}' String, 'myNthval' Repl from dual 

) 
,MyStrings as 
(select 'This is the first example {1} ' Str, 1 strnum from dual 
    union all 
    select 'In the Second example all values are shown {1} {2} {3} {Nth} ', 2 from dual 
    union all 
    select '{3} Is the value for the third', 3 from dual 
    union all 
    select '{Nth} Is the value for the Nth', 4 from dual 
) 
,pivot as (
    Select Rownum Pnum 
    From dual 
    Connect By Rownum <= 100 
) 
,StrtoRow as 
(
SELECT rownum rn 
     ,ms.strnum 
     ,REGEXP_SUBSTR (Str,'[^ ]+',1,pv.pnum) TXT 
    FROM MyStrings ms 
     ,pivot pv 
where REGEXP_SUBSTR (Str,'[^ ]+',1,pv.pnum) is not null 
) 
Select Listagg(NVL(Repl,TXT),' ') within group (order by rn) 
from 
(
Select sr.TXT, d.Repl, sr.strnum, sr.rn 
    from StrtoRow sr 
     ,dict d 
where sr.TXT = d.String(+) 
order by strnum, rn 
) group by strnum 
+0

これは、SQL唯一のソリューションを実装するためにWITH節と名誉題を大いに活用していますが、結果は解析するのがまだかなり難しいです(私たちにとっては)!うまく機能しているようですが、私のコードで実装した場合、同僚に正しいかどうかを確認するよう求めません。彼らは私を撃つだろう! :-) – StewS2

関連する問題