Hola Kernel, te pongo un ejemplo volcándolo en un Arreglo y recorriendo un Cursor, no se si se ajuste a tu escenario, la primera función lo vuelca en un arreglo y la segunda a un cursor y estos son los resultados, con sus veces de ejecución y los tiempos, saca tus conclusiones y ajústalo a tu escenario:

func_oid | line_number | line | exec_count | total_time | longest_time
----------+-------------+-----------------------------------------------------------------------------------------+------------+------------+--------------
68829 | 1 | | 0 | 0 | 0 68829 | 2 | DECLARE | 0 | 0 | 0 68829 | 3 | contador integer := 0; | 0 | 0 | 0 68829 | 4 | precio numeric; | 0 | 0 | 0 68829 | 5 | arreglo int[2]; | 0 | 0 | 0 68829 | 6 | BEGIN | 0 | 0 | 0 68829 | 7 | for arreglo in select array[prod_id,category] from products where prod_id>$1 LOOP | 1 | 26019 | 26019 68829 | 8 | contador:=contador+arreglo[2]; | 9869 | 13389 | 59 68829 | 9 | END LOOP; | 0 | 0 | 0 68829 | 10 | RETURN contador; | 1 | 3 | 3 68829 | 11 | END; | 0 | 0 | 0 68831 | 1 | | 0 | 0 | 0 68831 | 2 | DECLARE | 0 | 0 | 0 68831 | 3 | cur CURSOR FOR select array[prod_id,category] from products where prod_id>$1; | 0 | 0 | 0 68831 | 4 | contador integer := 0; | 0 | 0 | 0 68831 | 5 | arreglo int[2]; | 0 | 0 | 0 68831 | 6 | BEGIN | 0 | 0 | 0 68831 | 7 | OPEN cur; | 1 | 210 | 210 68831 | 8 | LOOP | 1 | 48382 | 48382 68831 | 9 | FETCH cur INTO arreglo; | 9870 | 24318 | 84 68831 | 10 | EXIT WHEN not found; | 9870 | 11754 | 44 68831 | 11 | contador:=contador+arreglo[2]; | 9869 | 9992 | 47 68831 | 12 | END LOOP; | 0 | 0 | 0 68831 | 13 | CLOSE cur; | 1 | 6 | 6 68831 | 14 | RETURN contador; | 1 | 2 | 2 68831 | 15 | END; | 0 | 0 | 0
(26 filas)

(END)

saludos


On 09/07/15 08:31, Kernel wrote:
Hola,

Estoy empezando a crear funciones en plpgsql, y la verdad tengo bastantes dudas


Tengo que recorrerme varias veces el resultado de un mismo query y la verdad no se cual es la mejor, la tabla va ha ser grande y sera una tabla muy concurrida, y necesito que la funcion sea muy rápida

Este es el query

    SELECT ubicacion,articulo,lote,sum(entradas-salidas)
        FROM    movi
        WHERE    movi.id_contenedor     =    a407.i_contenedor
        GROUP    BY ubidacion,articulo,lote
        HAVING    sum(entradas - salidas) <> 0
        ORDER    BY    ubidacion,articulo,lote

el resultado estará mas o menos entre 0 y 3 filas

Mis dudas :

- ¿la segunda vez  que intente hacer un loop, esta en cache y no cuesta ?
- ¿Mejor lo vuelco a un record.array y recorro el array las veces que necesite? ¿como lo vuelco?

- Declaro un cursor y solo lo habro una vez (con el OPEN) y luego lo recorro con fecth las veces que necesite?

- y la ultima que se me ocurre y mas limpia, si utilizo sentecias select sobre esta que actuaria como una subconsulta que si esta en cache iria rapido (esto ultimo es algo que creo yo)

Algo asi ....

SELECT   a. ...
from
    (SELECT ubicacion,articulo,lote,sum(entradas-salidas)
        FROM    movi
        WHERE    movi.id_contenedor     =    a407.i_contenedor
        GROUP    BY ubidacion,articulo,lote
        HAVING    sum(entradas - salidas) <> 0
        ORDER    BY    ubidacion,articulo,lote)) a
group by a. ....


Gracias ..

-
Enviado a la lista de correo pgsql-es-ayuda (pgsql-es-ayuda@postgresql.org)
Para cambiar tu suscripci�n:
http://www.postgresql.org/mailpref/pgsql-es-ayuda


-
Enviado a la lista de correo pgsql-es-ayuda (pgsql-es-ayuda@postgresql.org)
Para cambiar tu suscripci�n:
http://www.postgresql.org/mailpref/pgsql-es-ayuda

Responder a