PL / SQL - 在同一查询中使用相同的流水线函数两次

时间:2009-12-14 22:17:46

标签: sql oracle oracle10g pipelined-function

我正在尝试使用流水线功能来节省时间并减少查询中的冗余。 有问题的函数根据某些输入返回参考表中的数据。我选择的主数据表中的记录具有多个列,这些列都引用参考表。我遇到的问题是,当我尝试在查询中多次使用流水线函数时,我得到一个“游标已经打开”错误。

例如:

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),现在我得到“游标已经打开”错误。

流水线功能非常简单:

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的问题)?

我承认我是流水线功能的新手,所以我不是百分之百确定这是一个合适的用途,但它在当时是有道理的,我对其他想法持开放态度。)

2 个答案:

答案 0 :(得分: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;

未经测试,也不清楚您加入的是什么 - 因此加入条件为?

答案 1 :(得分:0)

您是否尝试在管道行之前将光标关闭在该流水线功能中?

OPEN C_OvrdVal(in_ID);
FETCH c_OrdVal INTO my_chunk_variable;
CLOSE C_OrdVal;
PIPE ROW my_chunk_variable;
RETURN;