PL / SQL - استخدم نفس وظيفة الأنابيب مرتين في نفس الاستعلام
-
19-09-2019 - |
سؤال
أحاول استخدام وظيفة خط أنابيب لتوفيرها في الوقت المحدد وتقليل التكرار في استفساراتي. تقوم الوظيفة المعنية بإرجاع البيانات من جدول مراجع يستند إلى بعض المدخلات. سجلات في جدول البيانات الرئيسي التي أختارها من خلال أعمدة متعددة تشير إليها جميعها إلى الجدول المرجعي. المشكلة التي أجريها هي أنه عندما أحاول استخدام وظيفة الأنابيب أكثر من مرة واحدة في الاستعلام، أحصل على خطأ "مؤشر مفتوح بالفعل".
علي سبيل المثال:
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٪ هذا الاستخدام المناسب، لكنه أمر منطقي في ذلك الوقت وأنا منفتح على الأفكار الأخرى؛)
المحلول
إذا كنت تستخدم وظائف خطوط الأنابيب، فأنت في الحد الأدنى 9i يعني أنه يمكنك استخدام الفقرة مع:
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;
غير مختبر، وليس من الواضح ما الذي تنضم إليه أيضا - وبالتالي ?
في معايير الانضمام.
نصائح أخرى
هل حاولت إغلاق مؤشرك بالفعل داخل وظيفة الأنابيب قبل صف الأنابيب؟
OPEN C_OvrdVal(in_ID);
FETCH c_OrdVal INTO my_chunk_variable;
CLOSE C_OrdVal;
PIPE ROW my_chunk_variable;
RETURN;