Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Página 1 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
Disparador 1. ______________________________________________________________________ 26
Disparador 2. ______________________________________________________________________ 26
Página 2 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
Las vistas pueden ser creadas por usuarios con suficiente privilegio (permiso Create View en
MySQL).
Una vez creada, una vista aparecerá ante nosotros como si se tratase de una tabla.
Para crear una vista recurrimos al comando Create View, cuya sintaxis es:
CREATE
[OR REPLACE]
[ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
[DEFINER = { user | CURRENT_USER }]
[SQL SECURITY { DEFINER | INVOKER }]
VIEW view_name [(column_list)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
Como ejemplo vamos a crear una vista de las actores cuyo nombre comience por la letra a.
Uno de los parámetros interesantes que no encontramos en otros gestores de bases de datos es el
que indica si vamos a utilizar el nivel de seguridad del creador o del invocador a la hora de permitir
a un usuario acceder a los datos de la vista.
Una transacción es un conjunto de operaciones SQL que debe llevarse a cabo de manera atómica.
Esto significa que todas las operaciones son indivisibles, o se llevan a cabo todas o ninguna debería
de ser válida.
Para definir transacciones de mayoría de SGBD tienen órdenes de inicio de transacción, validación
y anulación.
En MySQL el soporte de transacciones sólo es válido para las tablas tipo InnoDB.
Un ejemplo sería: Una base de datos de un banco. Las tablas Cliente y Moroso tipo innodb.
Página 3 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
START TRANSACTION;
insert into moroso select * from cliente where deuda>0;
delete from cliente where deuda>0;
COMMIT;
Si sucede algún error, por ejemplo hardware, entre las operaciones insert y delete, al reiniciarse
MySQL las transacciones no terminadas será canceladas y las tablas quedarán tal como estaban
antes de iniciarse la transacción. Si no sucede ningún fallo al encontrar COMMIT MySQL validará
la transacción.
A veces, cuando programemos con SQL, seremos nosotros los que anularemos transacciones
mediante la orden ROLLBACK, por ejemplo, tras efectuar alguna comprobación no satisfactoria.
Los procedimientos son compilados y almacenados en la base de datos. Una vez creados pueden ser
modificados de nuevo y eliminados. Además de un nombre y una serie de instrucciones SQL
asociadas un procedimiento puede recibir para su funcionamiento una serie de parámetros.
INSTRUCCIONES.
[datosparámetro]:
[IN | OUT | INOUT] nombre_parametro tipo
Es decir, para cada parámetro especificamos si un parámetro introduce datos al procedimiento, los
devuelve o ambas cosas. A continuación se define el nombre del parámetro y, por último, el tipo de
datos asociado.
Página 4 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
PROBLEMA: Entonces ¿si cada orden SQL acaba en ; como crear un procedimiento que incluya
más de una orden?. Paciencia, lo veremos enseguida.
Llamada a un procedimiento.
Una vez hemos creado nuestro primer procedimiento sólo nos queda hacerlo funcionar. Para ello
usaremos el comando CALL:
call CONSULTA_ACTOR();
Eliminación de un procedimiento.
Para poder eliminar un procedimiento previamente creado emplearemos la orden drop, tal y como
vemos a continuación:
Página 5 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
Por ejemplo:
Do hace que se asigne el valor a la variable sin producir salida de datos por
pantalla.
Tomando su valor de una consulta: utilizando la palabra clave INTO en una consulta de
selección.
Ejemplo:.........
declare actores integer;
select count(*)into actores
from actor;
............
4.- Delimitadores
Como la experiencia nos demuestra, cada vez que introducimos un “;” en una sentencia SQL
estamos indicando el final de esa sentencia. La sentencia de creación de un procedimiento
almacenado es también SQL y como tal necesita el empleo de dicho delimitador.
Esto nos aboca a un problema en aquellos procedimentos almacenados que precisen de más de una
orden SQL, ¿como diferenciar entre el punto y coma (;) que finaliza una sentencia
perteneciente al cuerpo del procedimiento almacenado y el que marca el final del
procedimiento almacenado?.
Página 6 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
Veamos un ejemplo:
1. Introducimos la aparición de BEGIN ... END como indicadores de comienzo y fin del cuerpo de
un procedimiento. Hasta ahora los procedimientos que habíamos usado como ejemplo no
precisaban recurrir a BEGIN ... END porque sólo constaban de una orden SQL.
delimiter //
create procedure cantidad_actor()
begin
declare actores integer default 0;
select count(*) into actores from actor;
select actores;
end //
delimiter ;
Página 7 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
En este apartado vamos a elaborar a modo de ejemplo un procedimiento que recibirá dos
parámetros, uno como entrada a modo de carácter y otro como salida a modo de entero.
La finalidad del procedimiento será presentar por pantalla aquellos actores cuyo nombre sea similar
al primer parámetro recibido y además contar cuantos registros cumplen esta condición. El número
de tales registros se devolverá en la segunda variable, que será de salida.
DELIMITER //
CREATE PROCEDURE busca_actores(
IN letra CHAR(2),
OUT actores INT
)
BEGIN
En el ejemplo anterior nos llama la atención el uso del carácter @ en el segundo parámetro. El
símbolo @ es empleado para crear variables de sesión cuya vida se limita al tiempo que se esté
conectado al sistema. Por tanto, si hemos creado una variable temporal, podemos obtener su valor
tras llamar al procedimiento:
select @cantidad;
Propuesta de actividades
Página 8 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
Ejemplo:
Delimiter //
Create procedure disponible(out comprueba integer)
Begin
Declare num_actores integer;
Select count(*) into num_actores from actor;
If num_actores<=10 then set comprueba=0;
Else set comprueba=1;
End if
End //
Delimiter ;
Delimiter //
Create procedure disponible(out comprueba integer)
Begin
Declare num_actores integer;
Select count(*) into num_actores from actor;
case num_actores
when <=10 then set comprueba=0;
Else set comprueba=1;
End case
End //
Delimiter ;
Esta estructura es equivalente a una estructura GOTO de Basic. Se apoya en la definición de una
etiqueta y en la vuelta a dicha etiqueta mediante las cláusulas Loop o Iterate, o bien la salida de
dicho fragmento mediante la cláusula Leave.
Página 9 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
[etiqueta_de_inicio:] REPEAT
Lista de instrucciones SQL
UNTIL condición END REPEAT [fin_etiqueta_de_inicio]
delimiter //
Página 10 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
Delimiter ;
CALL repite(1000);
SELECT @x;
La segunda de las construcciones que nos va a permitir crear bucles es la while…do…end while,
cuya forma de empleo general corresponde a la siguiente construcción:
WHILE v1 > 0 DO
...
SET v1 = v1 - 1;
END WHILE;
END
El anterior procedimiento repetiría 5 veces aquellas instrucciones SQL que indicásemos en la línea
con los puntos suspensivos.
Página 11 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
8.- Funciones
Pues estaba claro, en todo lenguaje de programación que se precie no pueden faltar las funciones.
Podemos decir que una función es equivalente a un procedimiento que devuelve un valor.
Vemos que la definición de una función es muy similar a la de un procedimiento salvo que
mediante returns especificamos el tipo de dato que la función devuelve.
Creación de funciones.
Veamos algunos ejemplos de funciones:
DELIMITER //
CREATE FUNCTION Hola (s CHAR(20)) RETURNS CHAR(50)
RETURN CONCAT('Hola, ',s,'!');
//
DELIMITER ;
La función Hola recibe como parámetro una cadena de 20 caracteres y devuelve una cadena de 50
caracteres, que será el resultado de una concatenación.
select hola(‘Mundooo’);
Fijémonos en que para usar una función usamos select en lugar de call.
delimiter //
create function cuenta_actores() returns integer
begin
declare cantidad integer default 0;
select count(*) into cantidad from actor;
return cantidad;
end//
delimiter ;
select cuenta_actores();
Página 12 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
Para poder ver los detalles de creación de una función emplearemos el comando show create,
ejemplos:
Para poder eliminar una función previamente creada emplearemos la orden drop, tal y como vemos
a continuación:
9.- Cursores
Hasta ahora en todos los procedimientos y funciones hemos usado variables de tipo sencillo
(integer, char, etc) capaces de almacenar en su interior un solo valor. A estos tipos se añade otro
más complejo como el cursor, con el que es posible operar sobre un conjunto de datos en lugar de
con un dato individual.
Una variable de tipo cursor permite recorrer, una a una, las filas de un conjunto de datos,
generalmente en el interior de un bucle while.
Como vemos las variables de tipo cursor se declaran como otra de tipo cualquiera, sin embargo, es a
la hora de asignar valores donde se encuentra la diferencia, ya que en ellas no almacenamos un
valor concreto sino el puntero de acceso a un grupo de datos que son los devueltos por la cláusula
select de la consulta asociada al cursor.
Para poder usar un cursor, una vez definido, recurrimos a las siguientes operaciones:
Página 13 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
• Open: la apertura es la primera operación que debe llevarse a cabo después de haberlo
declarado y antes de iniciar la recuperación de los datos. Basta con disponer el nombre del
cursor tras la sentencia OPEN.
• Fetch: esta sentencia se usará para recuperar una fila del conjunto de resultados y pasar a la
siguiente. Su sintaxis es Fetch nombre_cursor into variable1, var 2, ... var N. Las variables
deben seguir el mismo orden de aparición y tipos que los definidos en la declaración del
cursor.
• Close: cierra un cursor previamente abierto.
delimiter //
create procedure recorre_actor ()
begin
declare cont integer default 1;
declare nom char(64);
declare ap char(64);
declare c cursor for select nombre, apellidos from actor;
open c;
fetch c into nom,ap;
select concat(‘Actor numero ’,cont,’: ’,‘Nombre:’,nom,’ .Apellido:’,ap);
close c;
end//
delimiter ;
call recorre_actor();
El anterior ejemplo nos facilita comprender el uso de un cursor, ahora bien, sólo hemos recorrido el
primer elemento de la lista de valores devueltos en la declaración del cursor. ¿Qué sucede si
queremos recorrer todos los valores?
Respuesta: parece que debemos recurrir a modificar el procedimiento anterior añadiendo una
estructura de repetición, un bucle. Pero .... todo bucle debe detenerse alguna vez, ¿cómo sabemos
que hemos llegado al final de todos los datos y que no podemos seguir haciendo fetch al cursor?.
El handler_tipo puede asumir uno de los siguientes valores: CONTINUE, EXIT, UNDO.
La declaración del manejador puede cubrir una o más condiciones, que son expresadas separadas
por comas en el apartado valor_de_condicion. Si una de las condiciones indicadas se cumple, la
sentencia SQL especificada en el handler se ejecuta. La sentencia puede ser un comando simple o
un grupo de comandos comprendidos en una sección BEGIN ... END.
Página 14 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
CONTINUE: la ejecución de la rutina que originó el motivo del desencadenamiento del handler
continúa después de la ejecución del fragmento de código SQL que dió lugar a la activación del
manejador.
EXIT: la ejecución del fragmento BEGIN ... END dentro de la que se declaró el manejador termina.
UNDO: la operación que desencadenó la llamada al manejador se anula. Esta opción no está
implementada en MySql 5.0.
Cuando ocurre una situación para la que no se ha definido un handler la acción por defecto es
EXIT.
Los valores de condición, en MySql, que se hacen corresponder con el término SQLSTATE,
pueden ser cualquiera de los mostrados en el anexo I Valores de Condición.
Con todo lo anterior, vamos a ver un ejemplo de uso de handler que nos va a servir para poder
recorrer todos los datos de un cursor mediante un bucle. Para ello partiremos del procedimiento
recorre_actor definido anteriormente, al que añadiremos un handler y un bucle:
delimiter //
create procedure recorre_actor ()
begin
declare cont integer default 1;
declare fin integer default 0;
declare nom char(64);
declare ap char(64);
declare c cursor for select nombre, apellidos from actor;
declare continue handler for sqlstate '02000' set fin = 1;
open c;
repeat
if (fin=0) then
fetch c into nom,ap;
select concat(‘Actor numero ’,cont,’: ’,‘Nombre:’,nom,’ .Apellido:’,ap);
set cont=cont+1;
end if;
until fin=1 end repeat;
close c;
end//
delimiter ;
call recorre_actor();
Comentemos brevemente los cambios sufridos por el procedimiento recorre_actor, los cuales hemos
resaltado en negrita.
1. Se ha introducido una nueva variable llamada fin, la cual vale 0 y pasará a valer 1 cuando lo
indique un handler.
2. Se ha definido un handler de tipo CONTINUE que se desencadenará en caso de producirse
la condición SQLSTATE ‘02000’. Esta condición, si la buscamos en el anexo I (valores de
condición) se corresponde con:
Página 15 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
3. Lo anterior quiere decir que ese error se producirá cuando una operación fetch no produzca
datos, bien porque se haya llegado al final de un cursor o porque el cursor esté vacío. En ese
caso hemos especificado que la variable FIN tome el valor 1.
4. Por último, hemos añadido un bucle de tipo repeat until, controlado por la variable FIN, del
que sólo se saldrá cuando dicha variable pase a tomar el valor 1, es decir, una operación
fetch desencadene el handler programado con anterioridad.
Manejo de Errores:
Página 16 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
Página 17 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
Página 18 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
Ejemplos de Cursores:
Página 19 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
10.- Disparadores
Los disparadores, también llamados desencadenadores (triggers en inglés), permiten realizar tareas
de forma automática cuando una determinada circunstancia tiene lugar.
Podemos crear disparadores que se activen antes o después de una inserción, una actualización o un
borrado.
De esta forma se puede comprobar que los valores que se intenta introducir en una determinada
tabla cumplen aquellas condiciones que nos interesan, deteniendo la operación en caso de que se
detecte alguna incongruencia.
También es posible asociar un desencadenador a una operación de actualización de manera que una
modificación de los datos de una determinada tabla active, de forma automática, una actualización
en otra tabla, manteniendo sincronizados los datos que se requieran.
CREATE TRIGGER nombre momento evento ON tabla FOR EACH ROW instrucciones SQL.
Página 20 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
Nombre: es el nombre que recibirá el disparador. Aquel por el que nos referiremos a él cuando
queramos utilizarlo.
Momento: puede tomar los valores BEFORE (antes) y AFTER (después). Se utiliza para indicar si
las instrucciones asociadas al disparador se ejecutarán antes o después de la operación que lo activó.
Evento: indica el tipo de operación que activará el disparador. Se puede tratar de INSERT,
UPDATE o DELETE.
Creación de disparadores.
Veamos algunos ejemplos sobre creación de disparadores:
Vamos a crear un disparador, definido sobre la tabla persona, de forma que cualquier dato que se
inserte en dicha tabla sea transformado automáticamente a caracteres en mayúsculas, para ello nos
ayudaremos de la función UPPER(cadena), ya definida en SQL que devuelve transformada a
mayúsculas una cadena de texto que le haya sido pasada como parámetro.
Teniendo claro esta serie de puntos introduzcamos un nuevo dato importante. ¿Cómo sabe el
disparador los valores que se están tratando de modificar en la tabla?.
Para responder a esta pregunta entrar en juego los operadores NEW y OLD de la siguiente forma:
Página 21 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
OLD Para borrados. La forma de uso es OLD.nombre_atributo de forma que, por ejemplo
OLD.nombre sería el nombre que se va a eliminar o que se acaba de eliminar (dependiendo de si el
momento es Before o After).
Delimiter //
Create trigger persona_insert before insert on persona for each row
Begin
Set New.nombre=upper(new.nombre);
Set New.apellidos=upper(new.apellidos);
End//
Delimiter ;
Un segundo ejemplo, imaginemos que deseamos añadir a la tabla persona un nuevo campo llamado
abreviatura que se actualice automáticamente y cuyo valor sean las tres primeras letras del apellido
y las dos primeras letras del nombre en ese orden.
Forzamos la actualización de los registros existentes de forma que mantengan el mismo valor pero
salte el disparador:
Página 22 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
¿Se han actualizado los datos de la nueva inserción?. Evidentemente no, el disparador que hemos
programado está definido para funcionar tras una actualización. Si queremos que comience a
funcionar antes de una inserción deberemos crear un disparador tipo before insert, simplemente
transformando el disparador anterior en uno nuevo.
Ahora bien, existe un problema y es que ya tenemos definido un disparador para el evento before
insert sobre la tabla persona, por lo que deberíamos remodelarlo:
Drop trigger persona_insert;
Delimiter //
Create trigger persona_insert before insert on persona for each row
Begin
Set New.nombre=upper(new.nombre);
Set New.apellidos=upper(new.apellidos);
Set new.abreviatura=concat(left(new.apellidos,3),left(new.nombre,2));
End//
Delimiter ;
Actualizamos y comprobamos:
Update persona set nombre=nombre
Select * from persona;
Insertamos y comprobamos:
Insert into persona (nombre, apellidos) values (‘Rosa’,’Garcia’);
Select * from persona;
Evidentemente una vez que hemos actualizado los datos de la tabla podemos prescindir de
act_abrev y dejar en funcionamiento persona_insert. Para ello lo eliminaremos.
Eliminación de un disparador.
Para poder eliminar un disparador emplearemos la orden drop, tal y como vemos a continuación:
drop trigger act_abrev;
Página 23 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
Calcular un NIF
Crear una función llamada letranif que calcule y devuelva la letra del nif de un DNI, que recibirá a
modo de parámetro, como número entero.
Para desarrollar el ejercicio se recomienda utilizar las funciones para manipulación de cadenas de
texto que sean necesarias (consultar manual de referencia de MySql que se adjunta).
Validar un NIF
Crear una función llamada validanif que devuelva el valor 1 si el nif que ha recibido como
parámetro de tipo char(10) es válido, si el NIF recibido no es válido devolverá el valor 0.
Para desarrollar el ejercicio se recomienda utilizar las funciones para manipulación de cadenas de
texto que sean necesarias (consultar manual de referencia de MySql que se adjunta).
Validar un e-mail.
En este ejercicio vamos a crear la función emailok, que recibe como parámetro una cadena de texto
de 30 caracteres y devuelve el valor 1 si la cadena recibida corresponde a una dirección de correo
electrónico y 0 en caso contrario.
Consideramos que una dirección de correo es valida si al menos cumple que existan dos caracteres
iniciales, tras los cuales exista una arroba, a continuación al menos dos caracteres y por último un .
tras el cual al menos deben existir dos caracteres mas.
Para desarrollar el ejercicio se recomienda utilizar las funciones para manipulación de cadenas de
texto que sean necesarias (consultar manual de referencia de MySql que se adjunta).
Página 24 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
El siguiente cometido que vamos a afrontar va a ser crear un procedimiento que nos sirva para
introducir cómodamente datos en una tabla. Para ello, en primer lugar vamos a crear la tabla
SOLTERO con los siguientes campos:
El procedimiento deberá, a partir del Dni recibido y, apoyándose en la función LETRANIF creada
con anterioridad, calcular el NIF completo que será el valor que almacenará en la tabla.
En el caso del e-mail el procedimiento se apoyará en la función emailok de forma que si el email
recibido no es válido no deberá almacenarse sino que para esa persona el campo e-mail asumirá el
valor NULL.
Crearemos también el procedimiento insert_casado para insertar datos en la tabla CASADOS con
idénticas condiciones al procedimiento anterior.
Borrado de datos.
El siguiente ejercicio que vamos a desarrollar consistirá en crear los procedimientos que nos sirvan
para eliminar cómodamente datos de las tablas SOLTEROS y CASADOS.
Los procedimientos a crear serán Borra_Soltero y Borra_Casado, el usuario sólo indicará el DNI de
la persona a eliminar y los procedimientos se encargarán de calcular el NIF correspondiente a ficho
DNI y eliminarlo de la tabla. Si el DNI indicado no tiene equivalente NIF asociado significará que
dicha persona no existe en la tabla y el procedimiento deberá hacer que aparezca el mensaje “DNI:
nº_del_dni DESCONOCIDO. NO SE HAN BORRADO DATOS”.
Consulta de datos.
Crear un procedimiento llamado consulta_nombres que obtenga sólo aquellos solteros o casados
cuyo nombre sea similar a un párametro de tipo char pasado al procedimiento. La salida de datos
debe ser similar a “Casados como se llaman como VVVVVVV”, apareciendo a continuación los
datos de los casados que cumplen con el criterio y a continuación “Solteros que se llaman como
VVVVVVV” seguido de los correspondientes datos. Si en alguno de los dos casos no existen datos
que cumplan con el criterio en el correspondiente apartado deberá aparecer el mensaje “No existen
casados que cumplan el criterio” o “No existen casados que cumplan el criterio”, según el caso.
Página 25 de 26
ASGBD. Unidad 4. Automatización de tareas. Scripts.
Disparador 1.
Disparador 2.
Crear una tabla llamada Bajas con idénticos campos que las tablas solteros y casados junto con un
campo adicional llamado Estado que será un char (1) con valor C si la persona que estamos dando
de baja estaba casada y S si estaba soltera.
Una vez creada la tabla Bajas crear sendos disparadores a las tablas casados y solteros de forma que
ante una eliminación en las tablas casados y solteros los datos de la persona eliminada sean
anexados a la tabla bajas junto con su estado (C o S).
Página 26 de 26