2012-11-09 6 views
7

Ich habe zwei Tabellen.
One ist answer_step_dtl
Ein weiterer tag_mst als
Ersetzen Sie mehrere Tags in einer Zeile in Select-Anweisung von einer anderen Tabelle

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

folgen und so weiter.

Und meine tag_mst hat Werte wie diese

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

Nun meine Forderung ist dieses Ich möchte mit ersetzten Wert von Tag Mastantwortformular Antworttabelle auszuwählen. Es kann mehr als ein Tag in einem sein ans_desc.

dachte ich den Ansatz

  1. Schleife durch das Ergebnis der answer_dtl die Tags aus einzelnem Datensatz

  2. Schleife durch die mehr Tags im Datensatz holen und dann den Tag ersetzen

  3. in einer temporären Tabelle speichern und dann den Cursor für die neue tem Tabelle öffnen.

Ist dies der Ansatz? Oder gibt es einen einfachen Ansatz dafür?

+0

Ist es möglich, dass Sie zwei Tag-Namen in demselben 'ans_desc' haben? – Ben

+0

ja das ist das möglich sonst ist die @joe Lösung perfekt. –

+0

@Ben Ich habe Update meine Frage bitte sehen Sie es. –

Antwort

3

Edit: Bonus Abfrage (rekursiv) CTE, inspired by a note von @Rob van Wijk muss 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. 

Erste Antwort:

Sie können aus einer PL/SQL-Funktion verwenden. Das Folgende funktioniert auch, wenn mehrere Tags ersetzt werden müssen:

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 Ich werde dies anwenden und sehe es –

+0

dank @Vincent es funktioniert perfekt. Aber sie werden einige Overhead (offene Cursor Problem), wenn ich antwort_step_dtl hat 60 bis 70 Schritt und jeder Schritt hat einige Tag. –

+0

Dies liest Zeilen aus 'answer_step_dtl' nur einmal, und für jedes Tag erhalten Sie einen eindeutigen Index-Scan, so dass dies in Ordnung sein sollte. Es gibt kein Problem mit dem offenen Cursor, da die Funktion keine expliziten Cursor verwendet. Wenn Sie 11gR2 verwenden, können Sie die andere Abfrage ausprobieren und uns mitteilen, welche die schnellste in Ihrem Dataset ist. –

1

versuchen Sie dies:

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

wird es funktionieren, wenn ich zwei Tags hintereinander habe? –

+0

Ich habe versucht, durch Bearbeiten, aber für mehrere Tag es funktioniert nicht. –

+0

@krshekhar: Versuchen Sie dann, die Tabelle zu aktualisieren, anstatt –

Verwandte Themen