Creación de Cursores en MySQL

Creación de Cursores en MySQL 5
Un cursor es un objeto que apunta a las filas retornadas de una consulta. Esta característica permite manipular los datos de cada fila de forma individual. MySQL usa la palabra reservada CURSOR para declarar estos espacios de lectura.

¿Qué son los Cursores en MySQL?

Recuerda que cuando consultábamos tablas con SELECT, MySQL arrojaba rápidamente los registros en pantalla de un solo tiro y nosotros eramos felices. Pero hay momentos donde necesitarémos acceder a cada registro de forma individual.

Lo que quiere decir que un cursor permite acceder en tiempo real a los datos de cada fila de una consulta. Este mecanismo es de gran utilidad cuando vayamos a comunicar MySQL con aplicativos o realizar consultas complejas.

¿Como usar Cursores en MySQL?

Para implementar un cursor debemos tener en cuenta 4 fases de su funcionamiento:

Declaración
Apertura
Lectura
Cierre

1. DECLARACION

Al igual que una una variable, los cursores se declaran con la sentencia DECLARE. Debemos declararlos después de nuestras variables corrientes, de lo contrario MySQL, generará un error. Veamos la sintaxis:

DECLARE nombre_cursor CURSOR FOR ;

Este sería un ejemplo:

DECLARE cursor_edad CURSOR FOR
SELECT EDAD FROM CLIENTE
WHERE NOMBRE LIKE "a%";

No significa que el objeto cursor_edad vaya a guardar los datos de la consulta a la cual esta referenciando. Lo que hace es apuntar a la dirección de memoria del primer resultado de dicha consulta. Si tienes conocimientos en C++ se te hará mas fácil comprender esta interpretación.

2. APERTURA

En la fase de declaración la consulta a la que hace referencia el cursor, aun no se ha ejecutado. Para ejecutarla usaremos el comando OPEN. Sin esta apertura los resultados del cursor no pueden ser leídos por MySQL, por lo tanto se producirá un error.

Debes tener en cuenta que al abrir el cursor este sitúa un puntero a la primera fila arrojada por la consulta.

OPEN nombre_cursor;

3. LECTURA

La lectura de los resultados de un cursor se hace con el comando FETCH. Este nos permite acceder a la primer fila generada por la consulta. Si se vuelve a usar el cursor pasa a apuntar a la segunda fila, luego a la tercer y así sucesivamente hasta que el cursor no tenga resultados que referenciar.

FETCH nombre_cursor INTO variable1,variable2,...

Es importante tener variables declaradas para almacenar temporalmente los datos de las columnas de cada fila, generadas por la consulta. Estas variables lógicamente deben tener el mismo tipo de dato que el valor de la columna a almacenar, y luego relacionarlas con la sentencia INTO.

Por ejemplo, si quisiéramos almacenar el id, nombre y apellido del primer empleado de la tabla EMPLEADO,  hacemos lo siguiente:

-- Declaración de variables para el cursor
DECLARE ID INT;
DECLARE NOMBRE VARCHAR(100);
DECLARE APELLIDO VARCHAR(100);
DECLARE cursor_cliente CURSOR
FOR SELECT ID, NOMBRE, APELLIDO FROM CLIENTE;
OPEN cursor_cliente;
FETCH cursor_cliente INTO ID,NOMBRE,APELLIDO;
CLOSE cursor_cliente;

Me imagino que intuyes que si queremos recorrer todas las filas de la consulta, necesitaremos de alguna estructura repetitiva, ¿no es cierto?, claro!, incluir el comando FETCH dentro de un bucle permite leer todos los resultados de un cursor. Cuando el cursor llegue al final de los resultados de la consulta, entonces el bucle termina. Pero terminar un bucle de este tipo necesita una condición de parada especial en MySQL.

Existen manejadores de errores en MySQL para esta tarea, aunque por el momento no los hemos estudiado es necesario saber lo siguiente:

Cuando usamos FETCH en el cursor, pero ya no hay mas filas por retornar, MySQL arroja un error llamado "02000 NO DATA FECH". Así que lo que debemos hacer es crear un manejador para indicar que cuando suceda ese error, el programa no termine, pero que si termine el bucle. Veamos:

-- Declaración de un manejador de error tipo NOT FOUND
DECLARE CONTINUE HANDLER FOR NOT FOUND SET @hecho = TRUE;

Aquí indicamos que si ocurre un error tipoNOT FOUND, entonces asignemos a la variable @hecho el valor de TRUE. Con esa variable podremos manejar la terminación de nuestro bucle mas adelante.

4. CIERRE

Una vez leído todos los resultados del cursor, procedemos a cerrar y limpiar espacios de memoria con CLOSE.

CLOSE nombre_cursor;

Ejemplo de un Procedimiento con un Cursor

El siguiente es un ejemplo construido con fines educativos:
Cree un procedimiento en MySQL que imprima el código y el total acumulado de ventas del vendedor que mas facturó. Tenga en cuenta que el procedimiento debe recibir la fecha inicial y la fecha final, para estimar el lapso de tiempo en el que se calculará el acumulado.El anterior requerimiento se crea a partir de una minibase de datos para un sistema de facturación que tiene el siguiente diagrama entidad-relación:

Diagrama entidad relación sistema de facturación

Diagrama entidad relación de un sistema de facturación.
Diseñador de phpMyAdmin

Antes de desarrollar el procedimiento, especificaremos el flujo en las entradas, procesos y salidas del programa:

Entradas

Las variables fecha_inicio y fecha_final
Procesos Consultar las facturas que liquidó el vendedor en las fechas estipuladas como entrada.
Encontrar los detalles de cada factura asociada al vendedor.
Multiplicar el precio por la cantidad de cada detalle y guardarlo en la variable acumulado_ventas.
Comparar el acumulado_ventas de cada vendedor mediante un bucle, para obtener el mejor vendedor.

Salida
Mostrar en la pantalla el código y la variable acumulado_ventas del mejor vendedor.
Una vez comprendido estos pasos, solo queda implementar el código. Veamos:

DELIMITER //
CREATE PROCEDURE mejor_vendedor(fecha_inicio DATE, fecha_final DATE)
BEGIN
-- Declaración de variables
DECLARE ID_VENDEDOR INT;
DECLARE ACUMULADO_VENTAS INT;
DECLARE TEMPV INT DEFAULT 0;
DECLARE TEMPID INT DEFAULT 0;
-- Definición de la consulta
DECLARE mejor_vendedor_cursor CURSOR FOR
SELECT V.IDVENDEDOR,SUM(DF.UNIDADES*DF.PRECIO)
FROM VENDEDOR AS V INNER JOIN FACTURA AS F
ON V.IDVENDEDOR = F.IDVENDEDOR AND (F.FECHA BETWEEN fecha_inicio AND fecha_final)
INNER JOIN DETALLEFACTURA AS DF
ON F.IDFACTURA = DF.IDFACTURA
GROUP BY V.IDVENDEDOR;
-- Declaración de un manejador de error tipo NOT FOUND
DECLARE CONTINUE HANDLER FOR NOT FOUND SET @hecho = TRUE;
-- Abrimos el cursor
OPEN mejor_vendedor_cursor;
-- Comenzamos nuestro bucle de lectura
loop1: LOOP
-- Obtenemos la primera fila en la variables correspondientes
FETCH mejor_vendedor_cursor INTO ID_VENDEDOR, ACUMULADO_VENTAS;
-- Si el cursor se quedó sin elementos,
-- entonces nos salimos del bucle
IF @hecho THEN
LEAVE loop1;
END IF;
-- Guardamos el acumulado de ventas y el código
-- si el vendedor actual tiene mejores resultados
IF ACUMULADO_VENTAS>=TEMPV THEN
SET TEMPV = ACUMULADO_VENTAS;
SET TEMPID = ID_VENDEDOR;
END IF;
END LOOP loop1;
-- Cerramos el cursor
CLOSE mejor_vendedor_cursor;
-- Imprimimos el código y total acumulado de ventas del vendedor
SELECT TEMPID AS CODIGO_VENDEDOR, TEMPV AS TOTAL_VENTAS;
END//
DELIMITER ;

MySQL no permite que los cursores lean los resultados de una consulta desde el ultimo elemento hasta el primero. Usa ORDER BY para organizar tu mismo la información.

MySQL no permite que saltemos a una fila en particular para ahorrarnos tiempo, debemos recorrer obligatoriamente uno a uno los resultados.

James Revelo Urrea - Desarrollador independiente http://www.hermosaprogramacion.com

Fuente: este post proviene de Hermosa Programación, donde puedes consultar el contenido original.
¿Vulnera este post tus derechos? Pincha aquí.
Modificado:
¿Qué te ha parecido esta idea?

Esta idea proviene de:

Y estas son sus últimas ideas publicadas:

Recomendamos

Relacionado

informática bases de datos cursor ...

Un cursor es un objeto que te permite leer fila por fila los resultados que arroja una consulta. Lo que significa que ahora podremos ejecutar bloques de instrucciones que se relacionen individualmente con cada registro. A lo largo de este artículo estudiaremos los pasos necesarios para usar un cursor sobre una consulta. Veremos como usar el bucle WHILE para leer completamente la información y fina ...

informática bases de datos mysql ...

En este artículo veremos como integrar Php y Mysql para aumentar la funcionalidad de nuestros desarrollos web. Primero veremos como abrir la conexión en el servidor Mysql. Luego ejecutaremos comandos en nuestra base de datos a través de nuestra aplicación y finalmente aprenderemos a llamar procedimientos almacenados. Actualmente Php ha declarado obsoleta su API clásica de conexión MySQL para proye ...

Mysql_Select_Db Bases de Datos MySql Mysql_Connect ...

MySQL es uno de los gestores de bases de datos más utilizados en entornos en los cuales se emplea PHP ya que PHP dispone de numerosas funciones que se compaginan perfectamente con MySQL. La forma genérica de obtener información de tablas en Mysql es la siguiente: Inicie la conexión Preparación de la consulta SQL. Ejecución de la consulta. Procesamiento del resultado obtenido en el cursor.

informática bases de datos ejemplos ...

Un Trigger en MySQL es un programa almacenado(stored program), creado para ejecutarse automaticamente cuando ocurra un evento en nuestra base de datos. Dichos eventos son generados por los comandos INSERT, UPDATE y DELETE, los cuales hacen parte del DML(Data Modeling Languaje) de SQL. Esto significa que invocaremos nuestros Triggers para ejecutar un bloque de instrucciones que proteja, restrinja ...

informática bases de datos funciones ...

Una función en MySQL es una rutina creada para tomar unos parámetros, procesarlos y retornar en un salida. Se diferencian de los procedimientos en las siguientes características: Solamente pueden tener parámetros de entrada IN y no parámetros de salida OUT o INOUT Deben retornar en un valor con algún tipo de dato definido Pueden usarse en el contexto de una sentencia SQL Solo retornan un valor in ...

informática bases de datos conexión ...

Conectar tus aplicaciones Java a un servidor de bases de datos es imprescindible para la funcionalidad de una solución de Software. Al igual que Sql server y C#, Mysql y Java necesitan de una interfaz que proporcione las clases necesarias para gestionar una conexión.Para comprender el funcionamiento de este enlace comenzaremos explicando como adherir el API de conexión a nuestros IDEs ( en este ca ...

Ordenador Windows cambiar apariencia del raton windows 10 ...

Anteriormente existía un solo tipo de cursor, que todas las personas empleaban en Windows en las versiones anteriores. Sin embargo; en la actualidad se pueden tener otras formas o tipos de cursores que se han diseñado para Windows 10, por lo que existe una lista con varios tipos para que la persona lo cambie cuando lo desee. Aunque es importante acotar que no necesariamente son mejores o más atra ...

Linux

Si ha administrado un servidor Linux anteriormente, estará familiarizado con la pila LAMP (Linux, Apache, MySQL, PHP) comúnmente utilizada. Sin embargo, Apache, MySQL y PHP a veces pueden ser intensivos en recursos y pueden no ser los mejores para su servidor. En este tutorial, vamos a reemplazar todas y cada una de las partes de la pila, excepto Linux, con una alternativa mejor – Nginx, Mar ...

informática desarrollo android

En este tutorial descubriremos como usar bases de datos en SQLite para no perder la información de nuestras Aplicaciones Android. A medida que vayamos avanzando veremos la utilidad de clases como SQLiteOpenHelper, SQLiteDatabase, Cursor, CursorAdapter y de Herramientas como sqlite3 y SQLite Browser. Asumimos que tienes conocimientos básicos en SQLite Con el fin de facilitar tu aprendizaje usarem ...

Linux

¿Alguna vez ha querido acceder a sus fotos desde cualquier lugar a través de la Web, pero no ha querido suscribirse a soluciones patentadas como Google Photos, Photo Bucket, etc.? Presentamos Lychee , una herramienta autohospedada que permite a los usuarios gestionar, subir y catalogar sus grandes colecciones de fotos. Funciona en cualquier servidor web que tenga Apache2 (o NGINX), PHP y MySQL. En ...