在另一个表的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的结果从单个记录中获取标签
循环访问记录中的多个标记,然后替换标记
这是方法吗? 或者有没有简单的方法来做到这一点。
编辑:使用(递归)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