2008-09-17 33 views
9

Tengo una cadena que proviene de una tabla como "no se puede pagar {1}, como pago {2} con vencimiento el {3}". Quiero reemplazar {1} con algún valor, {2} con algún valor y {3} con algún valor.cómo reemplazar varias cadenas juntas en Oracle

¿Es posible reemplazar todas las 3 en una función de reemplazo? o ¿hay alguna forma en que pueda escribir directamente la consulta y obtener el valor reemplazado? Quiero reemplazar estas cadenas en el procedimiento almacenado de Oracle. La cadena original viene de una de las tablas. Solo estoy haciendo selecciones en esa tabla

y luego quiero reemplazar los valores {1}, {2}, {3} de esa cadena en el otro valor que tengo de otra tabla

+0

duplicado posible de [Múltiple SUSTITUIR función en Oracle] (https://stackoverflow.com/questions/2947623/multiple-replace-function-in-oracle) – Joaquinglezsantos

Respuesta

12

Aunque no es una llamada, puede anidar los replace() llamadas:

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

¿El segundo mytwoval falta comillas simples? –

+0

@SimonTheCat ¡Tienes razón! (A menos que mytwoval sea una variable) – hamishmcn

-1

Si usted está haciendo esto dentro de un sELECT, puede solo júntelo, si sus valores de reemplazo son columnas, usando concatenación de cadenas.

4

Si hay muchas variables para reemplazar y las tiene en otra tabla y si el número de variables es variable, puede usar un CTE recursivo para reemplazarlas. Un ejemplo a continuación. En la tabla fg_rulez pones las cuerdas con su reemplazo. En la tabla fg_data tiene sus cadenas de entrada.

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

Entonces, un solo replace.

Resultado:

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 

El símbolo de la terminología en lugar de la variable proviene de this duplicated question.

Oracle 11gR2

+0

Aliasing en la cláusula WITH es compatible desde Oracle 11gR2. – Stephan

+1

IMH esta es una respuesta excelente porque aborda el punto que lamentablemente solo se mencionó oblicuamente en la pregunta, es decir, permitir que los términos reemplazados se actualicen sin editar la consulta real (que es un escenario útil en un entorno controlado). – Neil

1

Si el número de valores para reemplazar es demasiado grande o si tiene que ser capaz de para mantenerlo fácilmente, también puede dividir la cadena, usar una tabla de diccionario y finalmente agregar los resultados

En el siguiente ejemplo Asumo que las palabras en la cadena se separan con blankspaces y el recuento de palabras en la cadena no será mayor de 100 (tabla dinámica cardinalidad)

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

Ese es un gran uso de la cláusula WITH y felicitaciones por implementar una solución solo de SQL, pero el resultado es aún bastante difícil (para algunos de nosotros) para analizar. Parece funcionar bien, pero si lo implementara en mi código, no le pediría a un compañero de trabajo que lo revise para ver si es correcto. ¡Me dispararían! :-) – StewS2

Cuestiones relacionadas