Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

Recorrer resultado de consulta dentro de procedimiento almacenado

Estas en el tema de Recorrer resultado de consulta dentro de procedimiento almacenado en el foro de Mysql en Foros del Web. Holas :) Mi consulta es esa: necesito saber si Mysql permite recorrer el resultado de una consulta hecha dentro de mysql, con mysql. Me explico. ...
  #1 (permalink)  
Antiguo 17/04/2008, 15:24
Avatar de quinqui  
Fecha de Ingreso: agosto-2004
Ubicación: Chile!
Mensajes: 776
Antigüedad: 19 años, 8 meses
Puntos: 56
Recorrer resultado de consulta dentro de procedimiento almacenado

Holas :)

Mi consulta es esa: necesito saber si Mysql permite recorrer el resultado de una consulta hecha dentro de mysql, con mysql.

Me explico. Tengo un procedimiento que obtiene datos de varias tablas y los guarda ordenados en una nueva tabla, que es temporal.

Lo que yo necesito es poder recorrer esta tabla pero desde mysql, por ejemplo, usando WHILE, etc., pues necesito realizar una serie de filtros que con el SELECT normal no se puede (necesito aplicar una función creada por mí en mysql que discrimina registros de esta tabla).

Para todo esto, necesitaría tener funciones que me retornen la cantidad de registros que tiene la tabla temporal, una función que me retorne la fila actual, etc. ¿Se puede?

Muchas gracias de antemano! Saludos!
__________________
pipus.... vieeeeeji plomius!!!
*quinqui site*
  #2 (permalink)  
Antiguo 17/04/2008, 20:59
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Re: Recorrer resultado de consulta dentro de procedimiento almacenado

El tema se resuelve por medio de:
1. Trazado de la lectura por medio de CURSOR y FETCH.
2. Manejo de HANDLER, para controlar los eventos de tabla.
3. Acciones repetitivas por medio de funciones de control de flujo: REPEAT ... END REPEAT y LOOP ... END LOOP, etc.

El manual de referencia tiene un capítulo entero dedicado al tema, pero lo esencial se puede resumir así:

1. Primero tienes que declarar todas las variables que vayas a usar para contener los datos de cada registro que leas. es necesario porque no puedes leer el registro en sí, sino que debes volcar los datos seleccionados dentro de variables y manipularlos en esas variables.
Esto es lo primero a definir, apenas después del BEGIN del store procedure.

2. Luego tienes que definir el CURSOR. Podemos decir que un cursor en un puntero que contiene la posición del registro de la consulta a una tabla según una sentencia de SELECT asociada al mismo. La sintaxis habitual es una sentencia select cualquiera, por ejemplo:
Código:
DECLARE traza1 CURSOR FOR 
SELECT  A, B, C, D, E 
FROM tabla1 
WHERE A = 23;
3. Luego tienes que ser capaz de saber cuándo has llegado al fin de la lectura de la tabla. Eso sucede cuando el puntero del cursor se intenta mover más allá del último regitro. En ese momento se produce un SQLSTATE cuyo valor indica el tipo de problema. El número de cada SQLSTATE está asociado a un error en la base de datos y están listados en un capítulo aparte.
El handler define no solamente la captura del error sino qué acción se realizará (nada, salir, deshacer) y la sintaxis en este caso será:
Código:
DECLARE CONTINUE HANDLER salida FOR SQLSTATE '20000' SET accion = 1;
La variable accion es también una variable que debes definir previamente y darle el valor cero (0):
Código:
DECLARE accion INT DEFAULT 0;
4. Finalmente, puedes escribir el cuerpo del procedimiento, hasta el momento que ya tengas la tabla temporal. Obviamente el cursor es un select dirigido a ella.
Lo primero es abrir el cursor, luego iniciar el ciclo de lectura y finalmente cerrarlo.
Código:
OPEN traza1;
REPEAT
   FETCH traza1 INTO A1, B1, C1, D1, E1;
...
Cuerpo de los procesos a realizar con los valores
...
UNTIL salida END REPEAT;

CLOSE traza1;
FETCH lo que hace es tomar la resultante de la consulta del cursor, registro a registro y volcarla a las variables. Obviamente la cantidad de variables debe ser igual a la cantidad de campos leídos en la consulta, así como también sus tipos de datos deben ser de la misma clase.
Cuando llega al final de la tabla resultado, e intenta leer de más, se produce el SQLSTATE 20000, la variable se pone en 1, y como es la condición de salida, sale del loop.
Dos últimos detalles:
1. El proceso es siempre de lectura hacia adelante. No puedes retroceder. En todo caso deberás abrir de nuevo el cursor (nueva ejecución), y rehacer el barrido.
2. No se pueden definir variables en el SP con posterioridad al CURSOR, ni se puede definir un HANDLER antes del CURSOR. Te daría un error de compilación.

Eso es todo.

Última edición por gnzsoloyo; 17/04/2008 a las 21:06
  #3 (permalink)  
Antiguo 18/04/2008, 10:36
Avatar de quinqui  
Fecha de Ingreso: agosto-2004
Ubicación: Chile!
Mensajes: 776
Antigüedad: 19 años, 8 meses
Puntos: 56
Re: Recorrer resultado de consulta dentro de procedimiento almacenado

O___O!! UUHH!!

Muchas gracias, gnzsoloyo!

Te cuento que cuando hice la pregunta, llegó un compañero de trabajo y él sabía la respuesta! Jajajaja! Bueno, me dijo que tenía que usar cursores, y leí la documentación de Mysql e hice el procedimiento almacenado con el ciclo REPEAT y todo ok. No me dio error de compilación, pero no me muestra los datos, o sea, no se cae, pero dice que no encontró datos, cuando si hago la misma consulta pero desde fuera sí encuentra.

Por lo que acabo de leer de tu post, me faltó agregar esa declaración de la variable tipo HANDLER........ Ahora entiendo que seguro por eso no me daba resultado :P

Muchas gracias! En cuanto lo agregue y pruebe comento de nuevo. Gracias otra vez ^___~ Saludos!
__________________
pipus.... vieeeeeji plomius!!!
*quinqui site*
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 2 personas (incluyéndote)




La zona horaria es GMT -6. Ahora son las 03:14.