【问题标题】:how to replace multiple strings together in Oracle如何在Oracle中一起替换多个字符串
【发布时间】:2010-09-10 04:14:33
【问题描述】:

我有一个来自表格的字符串,例如“无法付款{1},因为您的付款{2}到期 {3}”。我想用某个值替换 {1},用某个值替换 {2},用某个值替换 {3}。

是否可以在一个替换功能中替换所有 3 个?或者有什么方法可以直接编写查询并获取替换值?我想在 Oracle 存储过程中替换这些字符串原始字符串来自我的一张表我只是在该表上进行选择

然后我想将该字符串中的 {1},{2},{3} 值替换为另一个表中的另一个值

【问题讨论】:

标签: oracle string replace


【解决方案1】:

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

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

【讨论】:

  • 第二个 mytwoval 是否缺少单引号?
  • @SimonTheCat 你是对的! (除非 mytwoval 是一个变量)
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 自 Oracle 11gR2 起支持 WITH 子句中的别名。
    • IMH 这是一个很好的答案,因为它解决了在问题中仅被间接引用的问题,即允许在不编辑实际查询的情况下更新替换的术语(这是一个有用的场景受控环境)。
    【解决方案4】:

    如果要替换的值太多或者需要能够轻松维护,也可以拆分字符串,使用字典表,最后聚合结果

    在下面的示例中,我假设您的字符串中的单词用空格分隔,并且字符串中的字数不会大于 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
    

    【讨论】:

    • 这是一个很好的使用 WITH 子句和实现纯 SQL 解决方案的荣誉,但结果仍然很难解析(对于我们中的一些人)!它似乎工作得很好,但如果我在我的代码中实现,我不会要求同事检查它的正确性。他们会向我开枪的! :-)
    【解决方案5】:

    让我们编写与 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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-27
      • 2015-09-23
      • 2020-01-16
      • 2021-11-25
      • 1970-01-01
      • 1970-01-01
      • 2020-03-31
      相关资源
      最近更新 更多