2009-12-14 56 views
0

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

例如:

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

我承认我是新来的流水线功能,所以我不是100%肯定这是一个合适的使用,但它在当时是有道理的,我愿意接受其他想法;)

+0

游标定义可能存在错误 - “;” after xov – jva 2009-12-15 10:04:14

+0

@jva:光标单独测试时工作正常。 – FrustratedWithFormsDesigner 2009-12-15 14:43:03

+0

@Frustrated:不值得解决光标问题 - 您无需麻烦即可获得所需的功能。唯一的进一步优化是如果你可以将视图变成物化视图,但限制是非常有限的。 – 2009-12-15 21:42:21

回答

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; 

未经检验的,并且目前还不清楚要加入什么太 - 因此?上连接标准。

+0

嗯有趣... 这个查询不是唯一一个需要ordValXML功能的人 - 还有其他人 - 我的最后一个计数大约是6,并且还有可能会增加更多。我原来使用流水线函数(我在10g)的原因是,它似乎是最可以_reusable_解决方案。除了它没有按照我的想法工作。 :( – FrustratedWithFormsDesigner 2009-12-14 23:03:44

+2

@Frustrated:视图将是最可重复使用的解决方案 - 只需将WITH子句中封装的内容移动到视图中 – 2009-12-14 23:21:41

+0

对于流水线函数,优化器必须猜测基数等。因此,更容易获得错误的计划(特别是如果你在查询中有几个)我会去看看,但可能是一个'真正的'CREATE VIEW之一,而不是内联或WITH视图 – 2009-12-15 00:55:48

0

在管道排之前,您是否尝试过在流水线功能中实际关闭光标?

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

我认为光标for循环应该自动处理。 – FrustratedWithFormsDesigner 2009-12-15 14:41:59

相关问题