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-11 11:25:13
Message-ID: 4D551C99.7040100@fibertel.com.ar
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: arpug

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 Alejandro Brust 2011-02-14 19:15:52 genexus y lock exclusive mode
Previous Message Emanuel Calvo Franco 2011-02-10 16:06:51 Re: Llamadas recursivas en funciones de Base de Datos