Skip site navigation (1) Skip section navigation (2)

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 (view raw or flat)
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

arpug by date

Next:From: Alejandro BrustDate: 2011-02-14 19:15:52
Subject: genexus y lock exclusive mode
Previous:From: Emanuel Calvo FrancoDate: 2011-02-10 16:06:51
Subject: Re: Llamadas recursivas en funciones de Base de Datos

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group