En la lista general preguntaron lo mismo

LOOP
               FETCH ...;
               IF.....;
               EXIT WHEN NOT FOUND;
               ...

END LOOP;

En el manual no aparece este tipo de tecnica. Seria interesante agregarla


El día 8 de octubre de 2008 13:48, Oswaldo Hernández
<[EMAIL PROTECTED]> escribió:
> Alvaro Herrera escribió:
>>
>> Oswaldo Hernández escribió:
>>
>>> El problema se presenta en una funcion que elimina una serie de
>>> registros, pero, despues de eliminarlos aún necesito algunos datos de esos
>>> registro que he borrado. Al ya están eliminados no puedo hacer un select
>>> sobre ellos, y tampoco puedo procesar los datos antes de eliminar los
>>> registros puesto que entre la eliminacion y el procesado de los datos hay
>>> otra serie de operaciones que necesitan que estén en ese estado.
>>>
>>> Para solucionarlo habia pensado dos opciones: 1.- Guardar los datos que
>>> necesito en una tabla temporal y despues hacer un for..loop sobre la tabla
>>> temporal, y 2.- Cargarlos en un cursor y leer posteriormente los datos del
>>> cursor.
>>
>> No entiendo eso de cargar en un cursor.  Ayer escribí un artículo en la
>> lista sobre los cursores, échale un vistazo.
>
> Lei tu mensaje sobre los cursores, pero creo que no es el mismo caso, ya que
> aqui el fetch lee las tuplas de una en una al igual que haria un for..loop.
>
> Sobre lo de cargar el cursor, puede que no me explicara bien. Esta es una
> version reducida de lo que pretendo:
>
> CREATE OR REPLACE FUNCTION pruebas.test_cursor()
>  RETURNS boolean AS
> $BODY$
> declare
>    v_cursor    refcursor;
>    v_rec       record;
> begin
>    create table pruebas.test (c integer);
>    insert into pruebas.test values (1),(2),(3),(4),(5);
>
>    -- *carga* antes de la eliminacion
>    open v_cursor for select c from pruebas.test;
>    -- eliminacion
>    delete from pruebas.test;
>
>    -- ... otras operaciones
>
>    -- lectura de los datos almacenados en el cursor
>    loop
>        fetch v_cursor into v_rec;
>        if v_rec is null then exit; end if;
>        raise notice 'valor de cursor: %', v_rec.c;
>    end loop;
>    close v_cursor;
>
>    drop table pruebas.test;
>    return True;
> end
> $BODY$
>  LANGUAGE 'plpgsql' VOLATILE
>  COST 100;
>
>> Un cursor no es una
>> especie de tabla temporal al que puedas pasarle tuplas y después leerlas
>> de vuelta.  Las tuplas necesitan estar almacenadas en alguna parte; el
>> cursor no tiene almacenamiento propio.
>>
> Entiendo eso y de ahi mi comentario sobre que entendia que postgres
> procesaria internamente tanto una opcion como la otra de forma muy similar,
> almacenando los datos en alguna parte. La elección entre usar una tabla
> temporal y el cursor era simplemente una cuestión de estilo.
>
> De todas formas si recomiendas que es preferible utilizar tablas temporales
> para estos casos, seguiré tu consejo.
>
> Saludos.
> --
> *****************************************
> Oswaldo Hernández
> oswaldo (@) soft-com (.) es
> *****************************************
> PD:
> Antes de imprimir este mensaje, asegúrese de que es necesario.
> El medio ambiente está en nuestra mano.
> --
> TIP 7: no olvides aumentar la configuración del "free space map"
>
--
TIP 4: No hagas 'kill -9' a postmaster

Responder a