Pregunta

Estoy tratando de utilizar una función pipeline para ahorrar tiempo y reducir la redundancia en mis consultas. La función en cuestión devuelve datos desde una tabla de referencia basado en alguna entrada. Registros de la tabla de datos principal que estoy seleccionando de tener varias columnas que todos se refieren a la tabla de referencia. El problema me encuentro es que cuando intento utilizar la función pipeline más de una vez en la consulta, aparece un "cursor ya está abierto" error.

Por ejemplo:

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;

Esto funcionó bien hasta que he añadido la segunda referencia a la función de canalización (fn_getOvrdValXML), y ahora me sale el "cursor ya está abierto" error.

La función pipeline es muy simple:

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;

El cursor es igualmente 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;

¿Hay una manera de solucionar este problema, o debería tratar de abordar este problema (el problema de tener que hacer referencia a ovrd_val y dar salida a una XMLFOREST de la misma manera muchas muchas muchas muchas veces) de forma diferente?

Admito que soy nuevo en funciones pipeline así que no estoy 100% seguro de que este es un uso apropiado, pero tenía sentido en el momento y estoy abierto a otras ideas;)

¿Fue útil?

Solución

Si está utilizando funciones de tuberías, entonces estás en 9i mínimo que significa que puede utilizar la cláusula 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;

No comprobado, y no está claro lo que se está uniendo también -. Por lo tanto el ? sobre los criterios de unión

Otros consejos

¿Usted ha intentado realmente cerrar el cursor dentro de esa función pipeline antes del conexionado fila?

OPEN C_OvrdVal(in_ID);
FETCH c_OrdVal INTO my_chunk_variable;
CLOSE C_OrdVal;
PIPE ROW my_chunk_variable;
RETURN;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top