2008-09-17 21 views
9

ersetzen Ich habe eine Zeichenfolge aus einer Tabelle wie "kann nicht bezahlen {1}, wie Ihre Zahlung {2} fällig am {3}". Ich möchte {1} durch einen Wert ersetzen, {2} durch einen Wert und {3} durch einen Wert.Wie mehrere Zeichenfolgen in Oracle

Ist es möglich, alle 3 in einer Austauschfunktion zu ersetzen? oder gibt es eine Möglichkeit, ich kann direkt Anfrage schreiben und Wert ersetzt bekommen? Ich möchte diese Zeichenfolgen in Oracle gespeicherten Prozedur ersetzen die ursprüngliche Zeichenfolge stammt aus einer meiner Tabelle, die ich gerade an dieser Tabelle

und dann möchte ich ersetzen {1}, {2}, {3} Werte aus dieser Zeichenfolge auf den anderen Wert, den ich aus einer anderen Tabelle

+0

Mögliches Duplikat [Multiple REPLACE Funktion in Oracle] (https://stackoverflow.com/questions/2947623/multiple-replace-function-in-oracle) – Joaquinglezsantos

Antwort

12

Obwohl es nicht ein Anruf, können Sie nisten die replace() Anrufe:

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

Ist die zweite mytwoval fehlt einzelne Anführungszeichen? –

+0

@SimonTheCat Sie haben Recht! (Es sei denn, Mytwoval war eine Variable) – hamishmcn

-1

Wenn Sie diese innerhalb einer ausgewählten tun, können Sie Fügen Sie es einfach zusammen, wenn Ihre Ersatzwerte Spalten sind, indem Sie die String-Verkettung verwenden.

4

Wenn viele Variablen zu ersetzen sind und Sie sie in einer anderen Tabelle haben und wenn die Anzahl der Variablen variabel ist, können Sie einen rekursiven CTE verwenden, um sie zu ersetzen. Ein Beispiel unten. In Tabelle fg_rulez legen Sie die Zeichenfolgen mit ihrem Ersatz. In der Tabelle fg_data haben Sie Ihre Eingabezeichenfolgen.

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); 

So, eine einzige replace.

Ergebnis:

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 

Die Terminologie Symbol statt Variable stammt aus this duplicated question.

Oracle 11gR2

+0

Aliasing in WITH-Klausel wird seit Oracle 11gR2 unterstützt. – Stephan

+1

IMH das ist eine ausgezeichnete Antwort, weil es den Punkt anspricht, der in der Frage leider nur schief referenziert wurde, nämlich zu erlauben, dass die ersetzten Ausdrücke aktualisiert werden, ohne die tatsächliche Frage zu bearbeiten (was ein nützliches Szenario in einer kontrollierten Umgebung ist). – Neil

1

Wenn die Anzahl der Werte zu groß zu ersetzen ist, oder Sie müssen in der Lage sein, Um es einfach zu verwalten, können Sie die Zeichenfolge auch teilen, eine Dictionary-Tabelle verwenden und schließlich die Ergebnisse

aggregieren

Im Beispiel unten Ich gehe davon aus, dass die Worte in der Zeichenfolge mit blankspaces getrennt sind und die wordcount in der Zeichenfolge nicht größer sein als 100 (Pivot-Tabelle Mächtigkeit)

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

Das ist eine großartige Verwendung der WITH-Klausel und ein großes Lob für die Implementierung einer SQL-only-Lösung, aber das Ergebnis ist immer noch ziemlich hart (für einige von uns) zu analysieren! Es scheint gut zu funktionieren, aber wenn ich es in meinen Code implementiere, würde ich keinen Kollegen bitten, es auf Korrektheit zu überprüfen. Sie würden mich erschießen! :-) – StewS2

Verwandte Themen