Ver Mensaje Individual
  #4 (permalink)  
Antiguo 23/07/2014, 06:16
Avatar de gnzsoloyo
gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: problemilla Procedure

Por empezar, al menos hay un error conceptual: No puedes cerrar las iteraciones cruzadas.
Si abres LOOP 1 y LOOP 2, estando el segundo dentro del primero , siempre deben cerrarse o enviar a ciclo nuevo en el orden inverso, es decir respetando el anidamieento del proceso.
Me refiero puntualmente a esto:
Código MySQL:
Ver original
  1. crs_num_fact_loop:LOOP
  2. ...
  3. crs_cod_pro_loop:LOOP -- segundo LOOP donde realiza el la busqueda de nombre de productos, codigo y costo.
  4.         ...
  5.             IF total_registro >= crs_num_fact THEN
  6.               ...
  7.               iterate crs_num_fact_loop; -- cierra el primer LOOP <-- Cierre cruzado. Orden incorrecto
  8.               iterate crs_cod_pro_loop; -- cierra el segundo LOOP
  9.             END IF;
  10. END LOOP crs_cod_pro_loop;
  11. END LOOP crs_fact_loop;
Adicionalmente, tienes esto:
Código MySQL:
Ver original
  1. OPEN cursor_suma;
  2.    ...
  3.    OPEN crs_num_fact;
  4.    BEGIN
  5.          crs_num_fact_loop:LOOP -- LOOP donde recorrera las fechas que se filtraron
  6.          ...
  7.             crs_cod_pro_loop:LOOP
  8.             OPEN crs_cod_prod;  -- abre el LOOP <.. No abre un loop, abre un CURSOR
  9.             FETCH crs_cod_prod INTO cod_producto, nombre_producto,costo,nit;
  10.                     INSERT INTO informe VALUES('',fecha_factura,cod_producto,nombre_producto,costo,nit);
  11.                         IF total_registro >= crs_num_fact THEN
  12.                           CLOSE csr_num_fact; -- <-- Caso 1
  13.                           CLOSE csr_cod_prod; -- <-- Caso 2
  14.                           ...
  15.                         END IF;
  16.          END LOOP crs_cod_pro_loop;
  17.          END LOOP crs_fact_loop;
  18.     END;
Caso 1: Cierras un CURSOR que abriste fuera del loop. El loop fallará por el cursor cerrado
Caso 2: Cierras un CURSOR que abriste dentro del loop. Cada iteración vovlera a abrirlo y reeejecutar la query desde el principio. No tiene sentido.

Además no has dejado el HANDLER, por lo que cualquier fallo de cualquier tipo producirá problemas no administrados.

En las FAQs de MySQL yo postee un ejemplo detallado hace ya bastante tiempo, que te puede servir de referencia para ver mejor el tema. En cualquier caso, no te olvides que en los anidamientos se debe respetar la secuencia de aperturas y cierres.

Finalmente, un consejo: En muchísimos casos he visto que una secuencia de queries a tablas temporales son más eficientes que usar cursores. Yo estimo (no puedo hacer pruebas en este momento porque no estoy en casa), que tal vez rediseñando las consultas podrías llegar a obtener iguales resultados sin necesidad de ellos.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)