如何在Oracle中将多个字符串替换在一起

knsnq2tg  于 2023-02-03  发布在  Oracle
关注(0)|答案(5)|浏览(205)

我有一个字符串来自类似“无法支付{1},因为您的付款{2}到期日为{3}"的表。我想将{1}替换为某个值,将{2}替换为某个值,将{3}替换为某个值。
是否可以在一个替换函数中替换所有3个字符串?或者是否有任何方法可以直接编写查询并获得替换值?我想在Oracle存储过程中替换这些字符串原始字符串来自我的一个表我只是在该表上进行选择
然后我想将该字符串中的{1}、{2}、{3}值替换为另一个表中的另一个值

yyyllmsg

yyyllmsg1#

虽然不是一个调用,但可以嵌套replace()调用:

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

chhkpiq42#

如果有很多变量需要替换,并且你在另一个表中有它们,如果变量的数量是可变的,你可以使用递归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**
nqwrtyyt

nqwrtyyt3#

让我们仅将相同的示例作为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);
guicsvcw

guicsvcw4#

如果要替换的值太多,或者您需要能够轻松地维护它,您还可以拆分字符串,使用字典表,最后聚合结果
在下面的示例中,我假设字符串中的单词用空格分隔,并且字符串中的字数不会大于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 is used to split the stings from MyStrings. We use a cartesian join for this
    ,pivot as (
      Select Rownum Pnum
      From dual
      Connect By Rownum <= 100   
      )
    -- StrtoRow is basically a cartesian join between MyStings and Pivot. 
-- There as many rows as individual string elements in the Mystring Table
-- (Max = Numnber of rows Mystring table * 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
    )
    -- This is the main Select. 
    -- With the listagg function we group the string together in lines using the key strnum (group by)
   -- The NVL gets the translations: 
       -- if there is a Repl (Replacement from the dict table) then provide it, 
       -- Otherwise TXT (string without translation)
    Select Listagg(NVL(Repl,TXT),' ') within group (order by rn) 
    from
    (
    -- outher join between strings and the translations (not all strings have translations)
    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
yv5phkfx

yv5phkfx5#

如果您在select中执行此操作,则可以使用字符串连接将其拼凑在一起(如果您的替换值是列)。

相关问题