在另一个表的select语句中替换一行中的多个标记

我有两张桌子。
一个是answer_step_dtl
另一个是tag_mst,如下所示

Ans_code                      Ans_Desc
-------------------------------------------
50000000000000005770       Enter <B><APN></B> and press Ok.       
40000000000000000164       Enter <B><ACCOUNTNAME></B> in connection name.
40000000000000000165       Enter <B><ACCOUNTNAME></B> in <APN>.

等等。

而我的tag_mst具有这样的值

TAG_CODE                    TAG_NAME          TAG_VALUE
-------------------------------------------------------
100                          <APN>            EXAMPLE.COM
101                          <ACCOUNTNAME>    EXAMPLE

现在我的要求是这个我想选择标记桅杆替换值的答案表答案表。 在一个ans_desc中可以有多个标签

我正在考虑这个方法

  • 循环answer_dtl的结果从单个记录中获取标签

  • 循环访问记录中的多个标记,然后替换标记

  • 存储在一个临时表中,然后打开新的TEM表的光标。
  • 这是方法吗? 或者有没有简单的方法来做到这一点。


    编辑:使用(递归)CTE的奖金查询,受@Rob van Wijk的说明启发,需要11g(R2?):

    SQL> WITH data AS (
      2     SELECT ans_code, Ans_Desc, tag_name, tag_value,
      3            row_number() OVER (partition BY ans_code ORDER BY t.rowid) no,
      4            row_number() OVER
      5               (partition BY ans_code ORDER BY t.rowid DESC) is_last
      6        FROM answer_step_dtl a
      7        JOIN tag_mst t ON a.ans_desc LIKE '%' || t.tag_name || '%'
      8  ), n(ans_code, no, is_last, replaced) AS (
      9     SELECT ans_code, no n, is_last,
     10            replace (ans_desc, tag_name, tag_value) replaced
     11       FROM data
     12      WHERE no = 1
     13     UNION ALL
     14     SELECT d.ans_code, d.no, d.is_last,
     15            replace (n.replaced, d.tag_name, d.tag_value) replaced
     16       FROM data d
     17       JOIN n ON d.ans_code = n.ans_code
     18        AND d.no = n.no + 1
     19  )
     20  SELECT *
     21    FROM n
     22   WHERE is_last=1;
    
    ANS_CODE             NO IS_LAST REPLACED
    -------------------- -- ------- ---------------------------------------
    40000000000000000164  1       1 Enter <B>EXAMPLE</B> in connection
    50000000000000005770  1       1 Enter <B>EXAMPLE.COM</B> and press Ok.
    40000000000000000165  2       1 Enter <B>EXAMPLE</B> in EXAMPLE.COM.
    

    初始答案:

    你可以使用PL / SQL函数。 即使有几个标签要被替换,以下方法仍然可行:

    CREATE OR REPLACE FUNCTION replacetags(p_desc VARCHAR2)
       RETURN VARCHAR2 IS
       l_result  LONG := p_desc;
       l_tag_pos INTEGER := 1;
       l_tag     tag_mst.tag_name%TYPE;
    BEGIN
       LOOP
          l_tag     := regexp_substr(l_result, '<[^<]+>', l_tag_pos);
          l_tag_pos := regexp_instr(l_result, '<[^<]+>', l_tag_pos) + 1;
          EXIT WHEN l_tag IS NULL;
          BEGIN
             SELECT replace(l_result, l_tag, tag_value)
               INTO l_result
               FROM tag_mst
              WHERE tag_name = l_tag;
          EXCEPTION
             WHEN no_data_found THEN
                NULL; -- tag doesn't exist in tag_mst
          END;
       END LOOP;
       RETURN l_result;
    END;
    
    SQL> SELECT ans_code, replacetags(ans_desc)
      2    FROM answer_step_dtl;
    
    ANS_CODE              REPLACETAGS(ANS_DESC)
    --------------------- ----------------------------------------
    50000000000000005770  Enter <B>EXAMPLE.COM</B> and press Ok.
    40000000000000000164  Enter <B>EXAMPLE</B> in connection
    40000000000000000165  Enter <B>EXAMPLE</B> in EXAMPLE.COM.
    

    尝试这个:

    select d."Ans_code",replace("Ans_Desc","TAG_NAME","TAG_VALUE")
    from   answer_step_dtl d, tag_mst m
    where "Ans_Desc" like '%'|| "TAG_NAME" || '%'
    


    SQL小提琴演示

    链接地址: http://www.djcxy.com/p/66051.html

    上一篇: Replace multiple tags in a row in select statement from another table

    下一篇: Finding cross on the image