miércoles, 27 de abril de 2016

USO DE CURSORES EN PROCEDIMIENTOS ALMACENADOS (SPL) - Using Cursors in Informix Stored Procedures (SPL)

Dentro de un procedimiento almacenado se pueden usar cursores de forma parecida a como hemos visto en 4gl.

* Con FOREACH:

FOREACH
    SELECT id, nombre
        INTO idCliente, nombreCliente
       FROM clientes
     ORDER BY id

     RETURN idCliente, nombreCliente WITH RESUME;

END FOREACH;   
                     
En este caso la query asociada al CURSOR debe ser especificada inmediatamente despues de la palabra FOREACH.

Es importante recalcar que debemos utilizar la clausula 'WITH RESUME' si queremos que el bucle continue y obtener los resultados de todas las filas proporcionadas por la query.

* De forma DINAMICA:

Pongo el mismo ejemplo que en la entrada anterior del blog para que podais ver que hay muy pocas diferencias.

LET myQuery = "SELECT pedidos.id_pedido, pedidos.fecha FROM pedidos";
--
--Incluyo la tabla de paises si se ha definido un filtro
--
IF filtro IS NOT NULL THEN
    LET myQuery = TRIM(myQuery) || ", paises";
END IF;
LET myQuery = TRIM(myQuery) ||
    " WHERE pedidos.fecha BETWEEN '01/01/2015' AND '31/12/2015';
--
-- Incluyo las condiciones de Join con la tabla de paises
--
IF filtro IS NOT NULL THEN
    LET myQuery = TRIM(myQuery) ||
         "  AND paises.nombre = " || TRIM(filtro) ||
         "  AND pedidos.id_pais = paises.id_pais";
END IF;

Una vez montada la query en la variable de texto, declaramos el CURSOR:

--
-- Preparo la variable que contiene la query antes de declarar el cursor
-- 
PREPARE mySql FROM myQuery;
DECLARE myCursor CURSOR FOR  mySql;
OPEN myCursor;
FETCH myCursor INTO  idPedido, fechaPedido;
IF (SQLCODE = 0) THEN
        WHILE 1=1

                RETURN id_pedido, fechaPedido WITH RESUME;

               FETCH myCursor INTO idPedido, fechaPedido;
               IF (SQLCODE = 100) THEN
                     EXIT WHILE;
               END IF;  

        END WHILE; 
END IF; CLOSE myCursor;
FREE myCursor;
FREE mySql;

Si teneis cualquier duda me poneis un comentario y procuraré responderos lo antes posible.

Hasta pronto.

1 comentario:

  1. No sé, si todavía se pueden hacer consultas....
    Mi consulta es si hay alguna instrucción en SPL para ejecutar una cadena preparada, es decir, algo parecido a R4gl con la instrucción EXECUTE.

    Pr ejemplo:

    function f01(lnrsis)
    define lnrsis integer
    define lcad char(100)

    let lcad="insert into hfue_org select user,current,",lnrsis,",* from fue_org"

    prepare ecad from lcad

    execute ecad

    free ecad
    end function

    ResponderEliminar