0

パイプライン関数を使用して時間を節約し、クエリの冗長性を減らしようとしています。問題の関数は、何らかの入力に基づいて参照テーブルからデータを返します。私が選択しているメインデータテーブルのレコードには、すべて参照テーブルを参照する複数の列があります。私が遭遇した問題は、パイプライン関数をクエリで複数回使用しようとすると、「カーソルがすでに開いています」というエラーが発生することです。

例えば:

select xmlelement("genInf", xmlelement("ID", vt.ID),
                           xmlelement("vID", vt.V_ID),
                           xmlelement("vNum", vt.V_NUM),
                           xmlelement("terrDataCode", TERR_CODE.column_value), --data is based on reference table
                           xmlelement("ABValCode", AB_VAL_CD.column_value), --data is based on reference table
                           ...
from V_TAB vt, table(UTIL.fn_getOvrdValXML(vt.terr_cd_id)) TERR_CODE,
               table(UTIL.fn_getOvrdValXML(vt.ab_val_id)) AB_VAL_CD
where vt.ID = in_vID;

これは、パイプライン関数(fn_getOvrdValXML)への2番目の参照を追加するまでは正常に機能し、「カーソルは既に開いています」というエラーが発生します。

パイプライン関数は非常に単純です。

type t_XMLTab is table of XMLType; --this type is in the spec
....
function fn_getOvrdValXML(in_ID in ovrd.id%type) return t_XMLTab
        pipelined is
    begin
        for r in C_OvrdVal(in_ID) loop
            pipe row(r.XMLChunk);
        end loop;
        return;
    end;

カーソルも同様に単純です。

cursor C_OvrdVal(in_ID in ovrd.id%type) is
        select xmlforest(ID as "valueID", S_VAL as "sValue", U_VAL as "uplValue",
                          O_VAL as "oValue", O_IND as "oIndicator", F_VAL as "finalValue",
                          O_RSN as "reason") AS XMLChunk
        from ovrd_val xov;
        where xov.id = in_ID;

これを回避する方法はありますか、それともこの問題(ovrd_valを参照し、同じ方法で何度も何度もxmlforestを出力する必要があるという問題)に別の方法で取り組む必要がありますか?

私はパイプライン関数に慣れていないことを認めているので、これが適切な使用法であるかどうかは100%確信できませんが、当時は理にかなっており、他のアイデアも受け入れています;)

4

2 に答える 2

1

パイプライン関数を使用している場合は、9i以上であるため、WITH句を使用できます。

WITH ovrdValXML AS (
  select xov.id,
         xmlforest(ID as "valueID", S_VAL as "sValue", U_VAL as "uplValue",
                        O_VAL as "oValue", O_IND as "oIndicator", F_VAL as "finalValue",
                        O_RSN as "reason") AS XMLChunk
     from ovrd_val xov)
SELECT xmlelement("genInf", xmlelement("ID", vt.ID),
                       xmlelement("vID", vt.V_ID),
                       xmlelement("vNum", vt.V_NUM),
                       xmlelement("terrDataCode", TERR_CODE.column_value), --data is based on reference table
                       xmlelement("ABValCode", AB_VAL_CD.column_value), --data is based on reference table
                       ...
  FROM V_TAB vt
  JOIN ovrdValXML terr_code ON terr_code = vt.?
                           AND terr_code.id = vt.terr_cd_id
  JOIN ovrdValXML ab_val_cd ON ab_val_cd = vt.?
                           AND ab_val_cd.id = vt.ab_val_cd
 WHERE vt.id = IN_VID;

テストされておらず、何に参加しているのかも明確ではありません。したがって、?参加基準に基づいています。

于 2009-12-14T22:54:12.583 に答える
0

行をパイプする前に、そのパイプライン関数内で実際にカーソルを閉じてみましたか?

OPEN C_OvrdVal(in_ID);
FETCH c_OrdVal INTO my_chunk_variable;
CLOSE C_OrdVal;
PIPE ROW my_chunk_variable;
RETURN;
于 2009-12-15T10:06:39.363 に答える