2012-11-09 27 views
7

Tôi có hai bảng.
Một là answer_step_dtl
khác là tag_mst như sau
Thay thế nhiều thẻ liên tiếp trong câu lệnh chọn từ một bảng khác

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>. 

và vân vân.

Và tag_mst của tôi có giá trị như thế này

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

Bây giờ yêu cầu của tôi là điều này tôi muốn chọn bảng câu trả lời dạng câu trả lời có giá trị thay thế của thẻ mast. Có thể có nhiều hơn một thẻ trong một thẻ ans_desc.

Tôi đã suy nghĩ cách tiếp cận

  1. Vòng qua kết quả của answer_dtl lấy thẻ ra khỏi hồ sơ cá nhân

  2. vòng qua nhiều thẻ trong hồ sơ và sau đó thay thế tag

  3. lưu trữ trong bảng tạm thời và sau đó mở con trỏ cho bảng tem mới.

Đây có phải là phương pháp hay không. Hoặc là có cách tiếp cận dễ dàng để làm điều này.

+0

Có thể bạn có hai tên thẻ trong cùng một 'ans_desc' không? – Ben

+0

có điều này là có thể nếu không giải pháp @joe là hoàn hảo. –

+0

@Ben Tôi có cập nhật câu hỏi của tôi vui lòng xem nó. –

Trả lời

3

Edit: Bonus truy vấn sử dụng (recursive) CTE, inspired by a note từ @Rob van Wijk, cần 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. 

câu trả lời ban đầu:

Bạn có thể sử dụng của một hàm PL/SQL. Nội dung sau sẽ hoạt động ngay cả khi có một số thẻ được thay thế:

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. 
+0

thaks @Vincent Tôi sẽ áp dụng điều này và xem nó –

+0

nhờ @Vincent nó hoạt động hoàn hảo. Nhưng họ sẽ được một số chi phí (mở con trỏ vấn đề) nếu tôi answer_step_dtl có 60 đến 70 bước và mỗi bước có một số thẻ. –

+0

Điều này sẽ đọc các hàng từ 'answer_step_dtl' chỉ một lần và đối với mỗi thẻ, bạn sẽ nhận được chỉ mục quét duy nhất, vì vậy điều này sẽ ổn. Sẽ không có vấn đề con trỏ mở vì chức năng không sử dụng con trỏ rõ ràng :) Nếu bạn đang ở trên 11gR2, bạn có thể thử truy vấn khác và cho chúng tôi biết điều gì là nhanh nhất trên tập dữ liệu của bạn. –

1

thử điều này:

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 fiddle demo

+0

nó sẽ hoạt động nếu tôi có hai thẻ liên tiếp? –

+0

Tôi đã thử bằng cách chỉnh sửa nhưng đối với nhiều thẻ, nó không hoạt động. –

+0

@krshekhar: sau đó thử cập nhật bảng thay vì chọn –

Các vấn đề liên quan