Está en la página 1de 18

UNIVERSIDAD TÉCNICA DE MANABÍ

DEPARTAMENTO DE INFORMÁTICA

Administración de Base
de Datos

Tercer Semestre
Ing. Lorena Bowen Mendoza
ADMINISTRACIÓN DE BASES DE DATOS

PROCESAMIENTO DE
TRANSACCIONES
UNIDAD II
ADMINISTRACIÓN DE BASES DE DATOS

CONTENIDO A TRATAR HOY:


Cursores

Objetivo de la Clase:
Escribir procedimientos PL/SQL utilizando Cursores.

6/27/2020 Cognitive Cities Management Research Group (CMMA) 3


Cursores
PROCESAMIENTO DE TRANSACCIONES
CURSORES Los procedimientos y funciones anteriores son
sencillos, ya que comprenden la recuperación de
una sola fila.
• Recuerden que cuando se consulta tablas con SELECT, MySQL arrojaba
rápidamente los registros en pantalla de una sola vez y cumplíamos lo
que queríamos hacer. Pero hay momentos donde necesitamos acceder a
cada registro de forma individual.
• Un cursor debe usarse para las sentencias SELECT que regresen más de
una fila. Un cursor permite el almacenamiento y la iteración de un
conjunto de registros obtenidos mediante una sentencia SELECT.
• Un cursor permite acceder en tiempo real a los datos de cada fila de una
consulta. Este mecanismo es de gran utilidad cuando se vaya a
comunicar MySQL con aplicativos o realizar consultas complejas.
6/27/2020 Cognitive Cities Management Research Group (CMMA) 5
CURSORES

¿COMO USAR CURSORES EN MYSQL?


Para implementar un cursor debemos tener en cuenta 4 fases de
su funcionamiento:
1. Declaración
2. Apertura
3. Lectura
4. Cierre

6/27/2020 Cognitive Cities Management Research Group (CMMA) 6


CURSORES
1. DECLARACIÓN
• Al igual que una una variable, los cursores se declaran con la sentencia DECLARE. Se
debe declarar después de las variables corrientes, de lo contrario MySQL, generará un
error. La sintaxis:

DECLARE nombre_cursor CURSOR FOR consulta;

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.
6/27/2020 Cognitive Cities Management Research Group (CMMA) 7
CURSORES
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.
• Se debe tener en cuenta que al abrir el cursor este sitúa un puntero a
la primera fila arrojada por la consulta.

OPEN nombre_cursor;

6/27/2020 Cognitive Cities Management Research Group (CMMA) 8


CURSORES
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 tercera 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.
6/27/2020 Cognitive Cities Management Research Group (CMMA) 9
CURSORES
4. CIERRE
• Una vez leído todos los resultados del cursor, procedemos a cerrar y
limpiar espacios de memoria con CLOSE.
CLOSE nombre_cursor;

6/27/2020 Cognitive Cities Management Research Group (CMMA) 10


CURSORES
• -- Declaración de variables para el cursor
DECLARE V_Id INT; Por ejemplo, si quisiéramos almacenar
el id, nombre y apellido del primer empleado
DECLARE V_Nombre VARCHAR(100); de la tabla EMPLEADO, hacemos lo siguiente:
DECLARE V_Apellido VARCHAR(100);
DECLARE cursor_cliente CURSOR FOR
SELECT Id, nombre, apellido FROM Cliente;
OPEN cursor_cliente;
FETCH cursor_cliente INTO V_Id, V_Nombre, V_Apellido;
CLOSE cursor_cliente;
Si queremos 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.
6/27/2020 Cognitive Cities Management Research Group (CMMA) 11
CURSORES
HANDLERS
Un handler (manejadores de errores) en MySQL es invocado cuando se
da un evento o condición definida con anterioridad. Este evento está
siempre asociado con una condición de error, pero puedes tener tres
formas de definir el error:
 Como código de error de MySQL
 Como código SQLSTATE ANSI-standard
 Como nombre de condición, ejemplos: SQLEXCEPTION, SQLWARNING
y NOT FOUND.
Los cursores deben declararse antes de declarar los HANDLERS, y las
variables y condiciones deben declararse antes de declarar cursores o
HANDLERS.
6/27/2020 Cognitive Cities Management Research Group (CMMA) 12
CURSORES
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 hay
que hacer es crear un manejador para indicar que cuando suceda ese error,
el programa no termine, pero que si termine el bucle.
Ejemplo:
-- 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 tipo NOT FOUND, entonces asignemos
a la variable @hecho el valor de TRUE. Con esa variable podremos manejar
la terminación de nuestro bucle mas adelante.
6/27/2020 Cognitive Cities Management Research Group (CMMA) 13
CURSORES
• MySQL tiene sus propios códigos de error que son únicos para MySQL
Server. Por ejemplo:
DECLARE CONTINUE HANDLER FOR 1062 SET duplicate_key=1;
• Un código de error SQLSTATE es definido por ANSI standard y son
independientes de la base de datos, lo que significa que deberías tener el
mismo valor de error para cualquier base de datos ANSI compatible. Por
ejemplo:
DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET duplicate_key=1;
• Así, Oracle, SQL Server, DB2, y MySQL reportarán el mismo SQLSTATEvalue
(23000) cuando hay un error de primary key duplicada.

6/27/2020 Cognitive Cities Management Research Group (CMMA) 14


CURSORES
EJEMPLO LOOP Un ejemplo de funcionamiento del
LOOP. Realiza el conteo del 1 al 10.
• DELIMITER //
CREATE PROCEDURE simple_loop ( )
BEGIN
DECLARE counter BIGINT DEFAULT 0; Empieza la variable COUNTER en cero
MY_LOOP: LOOP
SET counter=counter+1; Incrementa en 1 la variable COUNTER
IF counter=10 THEN Si la variable COUNTER llega a 10 sale
LEAVE MY_LOOP;
END IF; del LOOP

SELECT counter;
END LOOP MY_LOOP;
END //
DELIMITER ;
• CALL simple_loop();

6/27/2020 Cognitive Cities Management Research Group (CMMA) 15


CURSORES
EJEMPLO CURSOR Se empieza el LOOP para recorrer
todos los registros seleccionados
del cursor

DELIMITER //
C1_LOOP: LOOP
CREATE PROCEDURE PruebaCursor()
Se crea la variable #Leyendo la fila del cursos y asignando a las variables
BEGIN Limite con valor FALSE
FETCH Lista INTO v_IdPersona, v_Apellido, v_Nombres;
DECLARE Limite BOOLEAN DEFAULT FALSE;
Cada vez que se ejecuta el FETCH
DECLARE v_IdPersona INTEGER; se lee un registro del cursor
IF Limite THEN
DECLARE v_Apellido VARCHAR(50);
Llenado del cursor LEAVE C1_LOOP; Cuando se terminan los registros
DECLARE v_Nombres VARCHAR(50); mediante la consulta del cursor Limite = TRUE y sale
END IF; del LOOP
DECLARE Lista cursor for
SELECT v_IdPersona, v_Apellido, v_Nombres;
SELECT IdPersona, ApellidoPaterno, Nombres
END LOOP C1_LOOP; Muestra los datos leídos en
FROM personas ; FETCH.
#Definición del Handler con la variable Limite
CLOSE Lista;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET
Limite cambia a valor TRUE
END // Cerrando el cursor
Limite = TRUE; cuando ya no hay mas datos DELIMITER ;

OPEN Lista; Abriendo el cursor


Ejecutando el procedimiento.

CALL PruebaCursor();
CURSORES
MODELO E/R DE LA UNIDAD EDUCATIVA

El siguiente cursor selecciona


los datos de los profesores que
dan las materias de DIBUJO,
CULTURA FISICA e INGLES, y
dependiendo del código del
profesor inserta registros en
una tabla.

6/27/2020 Cognitive Cities Management Research Group (CMMA) 17


CURSORES
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET
EJEMPLO Limite = TRUE;

DELIMITER //
OPEN Lista;
CREATE PROCEDURE PruebaCursor1()
C1_LOOP: LOOP
BEGIN
FETCH Lista INTO v_IdProfesor, v_IdEspecialidad, v_IdCurso,
DECLARE Limite BOOLEAN DEFAULT FALSE;
v_IdParalelo;
DECLARE v_IdProfesor INTEGER;
IF Limite THEN
DECLARE v_IdEspecialidad INTEGER;
LEAVE C1_LOOP;
DECLARE v_IdCurso INTEGER;
END IF;
DECLARE v_IdParalelo INTEGER;
IF v_IdProfesor > 4 THEN
#Llenado del cursor mediante la consulta
INSERT INTO tiposasignaturas VALUES(v_IdProfesor+10,
DECLARE Lista cursor for
“Mayor que cuatro”);
SELECT IdPersonaProfesor, IdEspecialidad, IdCurso,
ELSE
IdParalelo
INSERT INTO tiposasignaturas VALUES(v_IdProfesor+10,
FROM materias AS M1, Materiasprofesores AS M2
“Menor que cinco”);
WHERE M1.IdMateria = M2.IdMateria
END IF;
AND M1.NombreMateria IN ('DIBUJO','CULTURA FISICA',
END LOOP C1_LOOP;
'INGLES')
CLOSE Lista;
GROUP BY idpersonaprofesor, IdEspecialidad, IdCurso,
END //
IdParalelo ;
DELIMITER ;

También podría gustarte