7

私は2つのテーブルを持っています。
1 つは answer_step_dtl で
、もう 1 つは 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

今、私の要件は、タグマストの値を置き換えた回答フォームの回答テーブルを選択したいということです。1 つの ans_desc に複数のタグを含めることができます

アプローチを考えていた

  1. answer_dtl の結果をループして、個々のレコードからタグを取得します

  2. レコード内の複数のタグをループしてから、タグを置き換えます

  3. 一時テーブルに保存してから、新しい tem テーブルのカーソルを開きます。

これがアプローチですか。または、これを行う簡単な方法はありますか。

4

2 に答える 2

3

編集: @Rob van Wijkからのメモに触発された(再帰的) CTE を使用したボーナス クエリには、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.
于 2012-11-09T09:30:00.893 に答える
1

これを試して:

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フィドルデモ

于 2012-11-09T07:43:33.340 に答える