Question

Je suis en train d'utiliser une fonction pour économiser sur les pipe-line du temps et de réduire la redondance dans mes requêtes. La fonction en question renvoie les données à partir d'une table de référence basé sur une entrée. Enregistrements dans la table principale de données que je choisissais à partir ont plusieurs colonnes que tous se réfèrent à la table de référence. Le problème que je cours en est que lorsque je tente d'utiliser la fonction pipe-line plus d'une fois dans la requête, je reçois une erreur « curseur est déjà ouvert ».

Par exemple:

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;

Cela a fonctionné bien jusqu'à ce que j'ai ajouté la deuxième référence à ma fonction de pipeline (fn_getOvrdValXML), et je reçois maintenant l'erreur « curseur est déjà ouvert ».

La fonction est très simple pipe-line:

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;

Le curseur est tout aussi simple:

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;

Y at-il un moyen de contourner ce problème, ou devrais-je essayer de résoudre ce problème (le problème d'avoir à faire référence ovrd_val et la sortie d'un xmlforest de la même manière beaucoup beaucoup beaucoup de fois) différemment?

Je dois admettre que je suis nouveau aux fonctions canalisées je ne suis pas 100% sûr que ce soit une utilisation appropriée, mais il était logique à l'époque et je suis ouvert à d'autres idées;)

Était-ce utile?

La solution

Si vous utilisez des fonctions de pipeline, alors vous êtes sur minimum 9i qui signifie que vous pouvez utiliser la clause 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;

Non testé, et il est clair pas ce que vous vous joignez aussi -. D'où le ? sur les critères de jointure

Autres conseils

Avez-vous essayé de fermer réellement votre curseur dans cette fonction avant la tuyauterie ligne pipe-line?

OPEN C_OvrdVal(in_ID);
FETCH c_OrdVal INTO my_chunk_variable;
CLOSE C_OrdVal;
PIPE ROW my_chunk_variable;
RETURN;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top