Pregunta

Tengo una cadena proveniente de una tabla como "no puedo pagar{1}, ya que su pago{2}vence el {3}".Quiero reemplazar {1} con algún valor, {2} con algún valor y {3} con algún valor.

¿Es posible reemplazar los 3 en una función de reemplazo?¿O hay alguna forma de escribir una consulta directamente y obtener un valor reemplazado?Quiero reemplazar estas cadenas en el procedimiento almacenado de Oracle. La cadena original proviene de una de mis tablas. Solo estoy seleccionando en esa tabla.

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

¿Fue útil?

Solución

Aunque no es una llamada, puedes anidar la replace() llamadas:

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

Otros consejos

Si hay muchas variables para reemplazar y las tienes en otra tabla y si el número de variables es variable puedes 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 tienes tus 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 terminológico en lugar de variable proviene de Esta pregunta duplicada.

Oráculo 11gR2

Si la cantidad de valores a reemplazar es demasiado grande o necesita poder mantenerlos fácilmente, también puede dividir la cadena, usar una tabla de diccionario y finalmente agregar los resultados.

En el siguiente ejemplo, supongo que las palabras de la cadena están separadas por espacios en blanco y que el recuento de palabras de la cadena no será mayor que 100 (cardinalidad de la tabla dinámica).

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

Escribamos el mismo ejemplo solo como CTE:

with fg_rulez as (
  select 1 id,'<' symbol, 'less than' text from dual
  union all select 2, '>', 'greater than' from dual
   union all select 3, '$', 'dollars' from dual
  union all select 4, '+', 'and' from dual
),  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
), 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);

Si está haciendo esto dentro de una selección, puede simplemente unirlos, si sus valores de reemplazo son columnas, usando concatenación de cadenas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top