@andres18281:
Este tema, y este mismo procedimiento,
ya ha sido motivo de otro post (que deberías haber continuado y no abriur uno nuevo), y en ese momento te hice algunas observaciones que por lo visto no has tenido mínimamente en cuenta...
Por lo pronto te hice la observación de que estás haciendo jOINs implícitos, pero no estás poniendo las condiciones de JOIN en el WHERE, por lo que existe riesgo potencial de que se generen productos cartesianos.
Por otro lado, ya te había dicho que yo veía innecesario el uso de cursores para recorrer el resultado de un join, cuyo origen era el resultado de otra consulta, simplemente para hacer inserciones. un JOIN más complejo es suficiente para el caso.
Además, ya te había mencionado que tablas TEMPORARY son más prácticas para lo que necesitas hacer.
En resumen la idea es esta:
- En primera instancia, lo que intentas resolver es obtener todas aquellas facturas que están en un determinado período de tiempo. Eso lo haces con esto:
Yo aquí noto que podrías usar un BETWEEN para simplificar, pero eso es algo formal.
De esta consulta salen dos datos: Factura y fecha, y esos datos luego los recorres sólo para hacer eso:
Código MySQL:
Ver originalSELECT ord_cod_zap
,pro_nomb
,cal_cost
,pro_nit
FROM ord_compra oc
, Producto p
, Calzado c
WHERE ord_cod_fact
= codigo_factura
;
Esta segunda query tiene un problema: No se ve que haya una relación entre las tres tablas, o al menso no se está indicando.
Cuando MySQL se encuentra con eso, realiza una junta natural emparejando, implicitamente,
aquellos campos que entre dos tablas tengan el mismo nombre. Esto puede tener efectos extraños si dos tablas tienen un campo llamado "id", "nombre", "fecha" o cualquier otro con identica denominación,
sin importar si representan lo mismo.
¿Se entiende el riesgo?
Además, como de todos modos el filtro se aplica
luego de realizar el JOIN implícito, estás haciendo un
full table scan, que es una de las peores formas de consulta existentes, luego del producto cartesiano. Es muchísimo más eficiente usar JOIN explícitos, ya que estos sólo leen aquellos registros que coinciden entre tablas (especialmente cuando hay FKs definidas).
Bien, vamos a suponer que las tablas tienen bien distinguidos los nombres de sus campos, y que no se repiten entre tablas más que los nombres de las claves primarias y su respectiva referencia de clave foránea.
En ese contexto, la sintaxis debería ser:
Ahora bien, siendo que la query anterior devuelve fecha y numero de factura, y que lo que pareces querer es la fecha, para cada orden producto (calzado) vendido, las dos consultas bien podrían combinarse en una sola:
Código MySQL:
Ver originalSELECT fact_fecha
, ord_cod_zap
, pro_nomb
, cal_cost
, pro_nit
INNER JOIN ord_compra oc
ON f.fact_cod_fac
= oc.ord_cod_fact
En ese contexto, una sola consulta estaría devolviendo todo lo que buscas, y con precisión.
- Por otro lado, planteas que quieres una tabla temporal donde insertar esos datos, pero usas una tabla MEMORY para eso.
te comento que las tablas MEMORY son tablas de estructura persistente, pero contenido volatil, por lo que luego de ejecutarse el proceso es probable que se enceuntre vacía. O al menos que se vacíe de datos al cerrarse la conexión que la usa.
Eso es así
por feinición de la tabla.
Si lo que necesitas es una tabla, para luego consultarla en el acto, y que desaparezca, no necesitas una MEMORY, sino una TEMPORARY. Esta existe sólo durante la ejecucion del proceso, y se borra inmediatamente cuando termina.
Ahora bien, si no vas a matener persistencia del reporte, lo que te conviene es crear una temporary y usar el mismo SP para que devuelva la tabla resultado antes de que est desaparezca,
o simplemente usar todo el SP para que ejecute la consulta.
Tu decides...
Yo, personalmente, intentaría algo parecido a esto:
Código MySQL:
Ver original SELECT (@id
:=@id
+1)idreporte
, fact_fecha
, ord_cod_zap
, pro_nomb
, cal_cost
, pro_nit
INNER JOIN ord_compra oc
ON f.fact_cod_fac
= oc.ord_cod_fact
o bien simplemente:
Código MySQL:
Ver original SELECT (@id
:=@id
+1)idreporte
, fact_fecha
, ord_cod_zap
, pro_nomb
, cal_cost
, pro_nit
INNER JOIN ord_compra oc
ON f.fact_cod_fac
= oc.ord_cod_fact
Por supuesto, como ya te dije, estoy
suponiendo las relaciones entre tus tablas, porque no las has explictado.
Pero yo haría algo así.
De hecho, casi todas las ocasiones donde he usado inicialmente cursores, termino utilizando tablas temporary, porque los cursores son ineficientes.
Com onota final, observo que en las condiciones de al menos uno de los IFs estás saliendo del LOOP
antes de cerrar el cursor, por lo que el CLOSE al cursor jamás se ejecuta en esa instancia...
TEn cuidado con la lógica de ejecución.