Re: Llamadas recursivas en funciones de Base de Datos

From: Gustavo Vaccaro <gustavo_vaccaro(at)fibertel(dot)com(dot)ar>
To: arpug(at)postgresql(dot)org
Subject: Re: Llamadas recursivas en funciones de Base de Datos
Date: 2011-02-16 13:06:44
Message-ID: 4D5BCBE4.203@fibertel.com.ar
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: arpug

Disculpen que insista
¿pero alguien sabe porque me tira el error cuando uso una funcion en forma
recurvisa?
el error

ERROR: el cursor «c_ctamadre» ya está en uso
CONTEXT: función PL/pgSQL «fn_acumuxcuenta» en la línea 23 en OPEN
función PL/pgSQL «fn_acumuxcuenta» en la línea 29 en asignación

aparentemente se produce porque la declaracion del cursor "c_ctamadre" sigue
viva de una llamada de funcion a la otra, pero no se como hacerla privada de la
funcion.

Si alguien me puede ayudar, se lo voy a agradecer.

Saludos

Gustavo J. Vaccaro
http://www.gjv.com.ar

El 11/02/2011 08:25 a.m., Gustavo Vaccaro escribió:
> Emanuel,
> Ya me di cuenta que funcionan distintas. Me costo unas cuantas horas la
> migracion, pero valio la pena.
> Te paso el codigo completo de la funcion:
>
> CREATE OR REPLACE FUNCTION "public"."fn_acumuxcuenta" (
> "arg_nroemp" integer,
> "arg_nroserie" integer,
> "arg_cuenta" char,
> "arg_fecdes" date,
> "arg_fechas" date,
> "arg_dh" char
> )
> RETURNS numeric AS
> $body$
> declare c_monto decimal(15,2);
> declare s_recmov character(1);
> declare s_cuenta character(25);
> declare c_ctamadre no scroll cursor for select id_cuenta from
> plancta where id_nroemp = arg_nroemp and id_ctamadre = arg_cuenta and
> id_cuenta <> id_ctamadre order by id_cuenta asc;
> begin
> c_monto=0;
> select recmov into s_recmov from plancta where id_nroemp = arg_nroemp and
> id_cuenta = arg_cuenta;
> /* */
> if s_recmov = 'S' then
> select sum(case when arg_dh = 'D' then debe else haber end) into c_monto
> from asiren,asicab where asiren.id_nroemp = arg_nroemp and
> asiren.id_nroserie = arg_nroserie and asiren.id_cuenta = arg_cuenta and
> asicab.fecha between(arg_fecdes) and(arg_fechas) and
> asiren.id_nroemp = asicab.id_nroemp and asiren.id_nroserie =
> asicab.id_nroserie and
> asiren.id_nroasi = asicab.id_nroasi and asicab.anulado = 'N';
> /**/
> if c_monto is null then
> c_monto=0;
> end if;
> else
> open c_ctamadre;
> loop
> fetch next from c_ctamadre into s_cuenta;
> if not found then
> exit;
> end if;
>
> c_monto=c_monto+fn_acumuxcuenta(arg_nroemp,arg_nroserie,s_cuenta,arg_fecdes,arg_fechas,arg_dh);
> end loop;
> close c_ctamadre;
> end if;
> /* */
> return(c_monto);
> end
> $body$
> LANGUAGE 'plpgsql'
> VOLATILE
> CALLED ON NULL INPUT
> SECURITY INVOKER
> COST 100;
>
> Saludos
>
> Gustavo J. Vaccaro
> http://www.gjv.com.ar
>
>
> El 10/02/2011 01:06 p.m., Emanuel Calvo Franco escribió:
>> El día 10 de febrero de 2011 15:06, Gustavo Vaccaro
>> <gustavo_vaccaro(at)fibertel(dot)com(dot)ar> escribió:
>>> Hola,
>>> tengo una funcion (fn_acumuxcuenta) en postgres 8.4 que hace una llamada
>>> recursiva a si misma.
>>>
>>> *** FUNCION fn_acumuxcuenta *****
>>> declare c_monto decimal(15,2);
>>> declare c_ctamadre scroll cursor for select id_cuenta from
>>> plancta where id_nroemp = arg_nroemp and id_ctamadre = arg_cuenta and
>>> id_cuenta<> id_ctamadre order by id_cuenta asc;
>>> BEGIN
>>> .....
>>> *** mas codigo ****
>>> .....
>>> linea 23: open c_ctamadre;
>>> loop
>>> fetch next from c_ctamadre into s_cuenta;
>>> if not found then
>>> exit;
>>> end if;
>>> linea 29:
>>> c_monto=c_monto+fn_acumuxcuenta(arg_nroemp,arg_nroserie,s_cuenta,arg_fecdes,arg_fechas,arg_dh);
>>> end loop;
>>> close c_ctamadre;
>>>
>>> return(c_monto);
>>> END
>>>
>>> Esta funcion la utilizo en una vista para que me devuelva el monto total
>>> acumulado.
>>> Cuando ejecuto la vista me tira el siguiente error:
>>>
>>>
>>> ERROR: el cursor «c_ctamadre» ya está en uso
>>> CONTEXT: función PL/pgSQL «fn_acumuxcuenta» en la línea 23 en OPEN
>>> función PL/pgSQL «fn_acumuxcuenta» en la línea 29 en asignación
>>>
>>> ********** Error **********
>>>
>>> ERROR: el cursor «c_ctamadre» ya está en uso
>>> Estado SQL:42P03
>>> Contexto:función PL/pgSQL «fn_acumuxcuenta» en la línea 23 en OPEN
>>> función PL/pgSQL «fn_acumuxcuenta» en la línea 29 en asignación
>>>
>>> Agradeceria alguna ayuda para intentar solucionar el problema.
>>>
>>> La funcion proviene de una migracion de Sybase Adaptive Server Anywhere y la
>>> recusividad funcionaba perfecto.
>>>
>> Pero ambas bases funcionan totalmente distintas respecto al manejo de cursores.
>>
>> Podrías pegar más detalles del código? Quizás se pueda implementar de
>> otra manera....
>>
>>
>>
>>

In response to

Responses

Browse arpug by date

  From Date Subject
Next Message Emanuel Calvo Franco 2011-02-16 13:16:01 Re: Llamadas recursivas en funciones de Base de Datos
Previous Message Alejandro Brust 2011-02-14 19:15:52 genexus y lock exclusive mode