domingo, 8 de noviembre de 2015

[MySQL] Recorrer el resultado de un select dentro de un procedmiento almacenado o función





Muchas veces hay tareas en las que necesitas hacer consultas cruzadas, que muchas veces complican demasiado el codigo y pueden generar problemas a la hora de la ejecución, ademas que la depuración es mas complicada dentro tus funciones o procedimientos, por lo que en lo particular me gusta que muchas de las tareas las haga el motor de base de datos, asi generando una sola transacción remota, les comento un ejemplo: 

1) Tengo un procedimiento almacenado que libera los productos de un proceso en tienda, y estoy generando, este procedimiento recibe un texto, el cual el procedimiento parte y realiza las actividades. Lo llamaremos: stp_devuelve_producto(idusuario, productos)

2) Ahora quiero devolver todos los productos en un dia particular, por lo que necesitaria hacer una consulta del día, luego posteriormente de los datos recibidos, ejecutar las sentencias para devolver el producto, por lo que lo hare en el mismo procedimiento almacenado que llamaremos stp_cancel_day(dia, idusuario), usaremos CURSOR de mysql 


CREATE DEFINER=`root`@`localhost` PROCEDURE `stp_cancel_day`(pday datetime, pidusuario int)
BEGIN  
   -- Declaramos las variables necesarias 
   -- La primera para saber cuando se detendra la consulta
   DECLARE done INT DEFAULT FALSE;
   -- Esta variable son las que recibiran los elementos necesarios 
   DECLARE piddetalle int DEFAULT 0;
   -- La variable que declararemos para concatenar los resultados
   DECLARE cad text; 
   
   -- Recorre se llma la variable CURSOR que recorre en base a la consulta
   DECLARE recorre CURSOR FOR 
      SELECT idproducto FROM detalle_pedido WHERE day=pday AND estado='ABIERTO';     
   -- Se declara un manejador para saber cuando se tiene que detener 
   DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
   -- Se abre el cursor
   OPEN recorre; 
   SET cad = "";
   loop_recorre: LOOP   
       FETCH recorre INTO piddetalle,pidproducto;        
       -- Fetch lo utilizamos para leer cada uno de los registros
       -- If que permite salir del ciclo
       IF done THEN 
   LEAVE loop_recorre;
    END IF;
       -- Concatemos los datos 
       SET cad = CONCAT(cad,CAST(pidproducto AS CHAR),',',CAST(piddetalle AS CHAR),',');       
   END LOOP;
   -- cerramos el cursor 
   CLOSE recorre;    
   -- Devuelve productos
   call stp_devuelve_producto(pidusuario,cad);
  
END



Con esto podremos recorrer cualquier tabla y utilizar sus datos  espero sirva


6 comentarios:

  1. muchas gracias me sirvió mucho

    ResponderEliminar
  2. Excelente ayuda muchas gracias me sirvió de mucho

    ResponderEliminar
  3. Muy util, muchas gracias, dejo otro ejemplo de como actualizar otra tabla, me base en tu ejemplo
    DELIMITER $$
    DROP PROCEDURE IF EXISTS `spUtilsActualizaSaldosCliente` $$

    CREATE PROCEDURE `spUtilsActualizaSaldosCliente`(
    )

    BEGIN
    # -- La primera para saber cuando se detendra la consulta
    DECLARE done INT DEFAULT FALSE;
    -- Esta variable son las que recibiran los elementos necesarios
    DECLARE varClienteID int DEFAULT 0;
    DECLARE varSuma decimal (10,2) default 0;
    -- Recorre se llama la variable CURSOR que recorre en base a la consulta
    DECLARE arreglo CURSOR FOR
    SELECT FK_Clientes_id AS clienteID, sum(cImporteComida + cImporteEnvioCobrado) as suma
    FROM tPedidos
    WHERE cCancelado = 0 and cFechaHoraTerminaEntrega IS NOT NULL
    GROUP BY FK_Clientes_ID;

    -- Se declara un manejador para saber cuando se tiene que detener
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    BEGIN
    ROLLBACK;
    END;
    START TRANSACTION;
    -- Se abre el cursor
    OPEN arreglo;
    SET varClienteID = 0;
    SET varSuma = 0;

    loop_recorre: LOOP
    FETCH arreglo INTO varClienteID, varSuma;
    -- Fetch lo utilizamos para leer cada uno de los registros
    -- If que permite salir del ciclo
    IF done THEN
    LEAVE loop_recorre;
    END IF;

    UPDATE tClientes SET cVentaAcumulada = varSuma
    WHERE ID = varClienteID;

    END LOOP;
    -- cerramos el cursor
    CLOSE arreglo;
    END ;

    call spUtilsActualizaSaldosCliente();

    ResponderEliminar
  4. Buenas tardes, como puedo recorrer una consulta y que me genere los datos de todos los clientes a la ves con sus detalles

    ResponderEliminar