Я пытаюсь использовать конвейерную функцию, чтобы сэкономить время и уменьшить избыточность в моих запросах.
Рассматриваемая функция возвращает данные из справочной таблицы на основе некоторого ввода. Записи в основной таблице данных, из которых я выбираю, имеют несколько столбцов, которые все ссылаются на справочную таблицу. Проблема, с которой я сталкиваюсь, состоит в том, что, когда я пытаюсь использовать конвейерную функцию более одного раза в запросе, я получаю ошибку «курсор уже открыт».
Например:
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%, что это подходящее использование, но в то время это имело смысл, и я открыт для других идей;)