Creación de Cursores en MySQL
Creación de Cursores en MySQL
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?
Cuando consultábamos tablas con SELECT, MySQL arrojaba rápidamente los registros en pantalla,
como resultado de la consulta ejecutada. Pero hay momentos donde necesitaremos 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.
¿Cómo 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 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: Declarar un cursor que muestre la lista de los clientes cuyo apellido
comienza con la letra c.
DECLARE CURSOR_CLIENTE CURSOR FOR
SELECT CONCAT(P.APE,' ',P.NOM)
FROM CLIENTE C, PERSONA P
WHERE C.DNI=P.DNI AND P.APE LIKE 'C%';
NOTA: Tener en cuenta que el objeto cursor_cliente lo que hace es apuntar a la dirección de
memoria del primer resultado de dicha consulta, y para guardar los datos de la consulta a la cual
está referenciando, se deberá implementar otros mecanismos dentro de la consulta a implementar.
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 primera fila generada por la consulta. Si se vuelve a usar el cursor pasa a apuntar a la segunda
fila, luego al tercer y así sucesivamente hasta que el cursor no tenga resultados que referenciar.
FETCH nombre_cursor INTO variable1,variable2,...
4. CIERRE
Una vez leído todos los resultados del cursor, procedemos a cerrar y limpiar espacios de memoria
con CLOSE.
CLOSE nombre_cursor;
NOTA: 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, implementar un cursor que almacene los apellidos y nombres, ruc y la persona de
contacto del primer proveedor registrado en el sistema.
DELIMITER$$
CREATE PROCEDURE PROVERDOR_CUR()
BEGIN
#DECLARACION DE VARIABLES PARA EL CURSOS
DECLARE APE_NOM VARCHAR(100);
DECLARE RUC VARCHAR(11);
DECLARE CONTACTO VARCHAR(100);
#DECLARAMOS EL CURSOR
DECLARE CUR_PROV CURSOR FOR
#LE INSTANCIAMOS LA CONSULTA AL CURSOR
SELECT CONCAT(P.APE,' ',P.NOM),P.RUC,PR.PERSONA_CONTACTO
FROM PERSONA P, PROVEEDORES PR
WHERE P.DNI=PR.PERSONA_DNI;
#ABRIMOS EL CURSOR
OPEN CUR_PROV;
#LEEMOS EL CURSOR
FETCH CUR_PROV INTO APE_NOM,RUC,CONTACTO;
#CERRAMOS EL CURSOR
CLOSE CUR_PROV;
SELECT APE_NOM,RUC,CONTACTO;
END$$
DELIMITER;
Para recorrer todas las filas de la consulta, necesitaremos de alguna estructura repetitiva, 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.
Cuando usamos FETCH en el cursor, pero ya no hay más 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.
DELIMITER$$
CREATE PROCEDURE CURSOR_RUC(C_RUC VARCHAR(200))
BEGIN
DECLARE RUC VARCHAR(11) DEFAULT "";
DECLARE HAY INT DEFAULT 0;
DECLARE CURSOR_RUC CURSOR FOR
SELECT P.RUC
FROM PERSONA P, PROVEEDORES PR
WHERE P.DNI=PR.PERSONA_DNI;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET HAY= 1;
OPEN CURSOR_RUC;
LOOP1:LOOP
FETCH CURSOR_RUC INTO RUC;
SET C_RUC = CONCAT(RUC,";",C_RUC);
IF HAY=1 THEN
LEAVE LOOP1;
END IF;
END LOOP LOOP1;
SELECT C_RUC;
CLOSE CURSOR_RUC;
END$$
DELIMITER;
SET @C_RUC="";
CALL CURSOR_RUC(@C_RUC);