Está en la página 1de 26

IES Suárez de Figueroa- @vanza

Administración de sistemas informáticos en red


Gestión de bases de datos Unidad 6. Construcción de guiones

Unidad 6. Construcción de guiones

Índice

1. Introducción 2
2. Variables de usuario 3
3. Procedimientos almacenados. 3
4. Funciones 8
5. Estructuras de control 10
6. Manipuladores de error 16
7. Manejo de cursores 18
8. Disparadores o triggers 24
9. Para saber más 26

1
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

1. Introducción

Mediante SQL, como hemos estudiado, se pueden consultar datos de una base de
datos, realizar inserciones, borrados y actualizaciones. Pero además de todo esto,
este lenguaje permite la automatización de tareas, es decir, ofrece la posibilidad de
guardar bajo un nombre un grupo de sentencias que se ejecutan a menudo y hacer
referencia a ese nombre cada vez que queramos ejecutarlas.

En esta unidad se estudia la forma de crear estos bloques de código, que integran
el lenguaje SQL, con sentencias de control propias de un lenguaje de programación,
como decisiones, bucles, etc. Esto es a lo que se llama guiones, scripts, etc.

Desde el punto de vista de las bases de datos, estos guiones o scripts se llaman
procedimientos, funciones, disparadores (triggers) y cursores.

- Procedimientos. Se trata de un conjunto de instrucciones SQL que se guardan


en el servidor y se ejecutan cuando ese procedimiento es llamado.
- Funciones. Conjunto de instrucciones que devuelven un valor. Para ejecutarlas
es necesario hacer referencia a su nombre, como sucede con los
procedimientos.
- Triggers. Procedimientos que se ejecutan automáticamente cuando se lleva a
cabo una determinada acción. Esta acción puede ser la inserción de una fila o
la conexión de un usuario, etc. En MariaDB, los triggers pueden utilizarse para
sentencias INSERT, UPDATE y DELETE. Son útiles para prevenir errores y
mejorar la administración de la base de datos sin necesidad de que el usuario
intervenga, ya que su ejecución va ligada a una instrucción de inserción,
eliminación o actualización.
- Cursores. Son grupos de sentencias que nos permiten tratar individualmente
las filas devueltas por una SELECT.

Entre las ventajas que aportan estos elementos tenemos:

- Permiten que se gestionen autorizaciones de ejecución sobre ellos.


- Pueden agruparse en librerías y ser utilizados por otros lenguajes.
- Mejoran el rendimiento, ya que están almacenados en la base de datos.
- Se simplifican las tareas cotidianas.
- Un procedimiento almacenado en el servidor ayuda a mantener la consistencia
y la integridad de los datos, ya que evita que éstos puedan ser corrompidos por
el acceso de programas defectuosos.
- Permiten la validación de datos, y se integran en la estructura de la base de
datos.
- Son dinámicos ya que admiten parámetros que se pasan antes de su ejecución
y pueden realizar diferentes tareas dependiendo de esos parámetros que se
hayan pasado

Entre sus inconvenientes están el que pueden resultar complejos de programar y


mantener, y además consumen recursos del servidor, a veces de forma excesiva.

2
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

2. Variables de usuario.

Una variable de usuario permite almacenar un valor y referirnos a él más tarde.


También pueden pasarse de una sentencia a otra. Las variables 'de usuario' no
pueden ser vistas por otros usuarios y desaparecen cuando la conexión se cierra.

Para crear una variable de usuario:

SET @NombreVariable1 = Expresión [, @NombreVariable2 = Expresión] …

Ejemplo: Set @salario=1000;

Otra forma de crearla mediante SELECT.

Ejemplo: Select @MaxSalario:= max(salario) from empleados;

Estas variables pueden ser utilizadas en cualquier lugar donde se espere una
expresión, siempre que no se espere un valor literal o constante, como tras LIMIT.

No son case-sensitive, es decir, @nombre y @Nombre nos estamos refiriendo a


la misma variable.

Un ejemplo de uso. Averiguamos el precio medio de compra y más tarde


mostramos los productos cuyo precio de compra supera ese valor medio. Observa
como las sentencias del script finalizan con punto y coma (;). Esto puede servirnos
para descomponer una sentencia compleja en partes y de esta forma hacerla más
sencilla.

3. Procedimientos almacenados.

Los procedimientos son rutinas o subprogramas compuestos por un conjunto de


sentencias SQL agrupadas lógicamente para realizar una tarea específica, se guardan
en la base de datos y se ejecutan como una unidad cuando son invocados por su
nombre.

Sus ventajas.
- Residen en el servidor, por tanto para ser utilizados sólo es necesario que
desde el cliente se haga referencia a su nombre. Su inconveniente es que el
servidor recibe una mayor carga de trabajo.
- Permiten que aplicaciones y usuarios no accedan directamente a las tablas,
sino que se comuniquen con estas a través de los mismos. Proporcionan un
entorno de ejecución seguro.
- Agilizan las comunicaciones con el cliente.

3
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

Para que podemos usar un procedimiento almacenado:

- llevar a cabo operaciones de inserción complejas en las que puedan intervenir


varias tablas.
- obtener un conjunto de resultados (registros) mediante consultas complejas
que requieren varios pasos
- validar de datos
- llevar a cabo operaciones de actualización y borrado

3.1. Creación de procedimientos almacenados.

Para crear un procedimiento almacenado se usa la siguiente sintaxis:

CREATE PROCEDURE NombreProcedimiento ([parámetro1 [, parámetro2,..]])


[características …]
BEGIN
CuerpoDelProcedimiento
END

Los parámetros son datos que se le pasan al procedimiento y que este utiliza para
realizar sus cálculos.

Los ​parámetros​ se declaran de esta forma:

[IN | OUT | INOUT] NombreParámetro Tipo

Un parámetro IN es sólo de lectura. El procedimiento puede acceder a su valor


pero no modificarlo. Es lo más habitual y la opción por defecto.
Un parámetro OUT es de escritura. El procedimiento proporciona un valor al
exterior a través de este parámetro.
Finalmente un parámetro INOUT es de lectura/escritura, el procedimiento puede
leerlo y modificarlo.

El ​Tipo se utiliza para asignar un tipo de datos al parámetro. Estos tipos de datos
son los propios de MariaDB vistos en la sección de creación de tablas.

Es obligatorio escribir una lista de parámetros aunque sea vacía ().

Las ​características​:

LANGUAGE SQL
| [NOT] DETERMINISTIC
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
| COMMENT 'CadenaComentario'

- LANGUAGE SQL. Para indicar que el cuerpo del procedimiento está escrito en
lenguaje SQL y no se cuela código en otro lenguaje.
- CONTAINS. Cláusula informativa. Para indicar al servidor que el procedimiento
lee datos, modifica datos o ninguna de ellas (SQL).

4
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

- [NOT] DETERMINISTIC. Una función es determinista si siempre devuelve el


mismo valor para los mismos datos de entrada. En caso contrario es NOT
DETERMINISTIC, que es el valor por defecto.
- SQL SECURITY { DEFINER | INVOKER }. Esto es importante para especificar
el contexto de seguridad bajo el que se ejecutará el procedimiento. DEFINER
indica que se ejecutará usando los permisos del usuario que los creó (valor por
defecto), con INVOKER se usan los permisos del usuario que realiza la
llamada.

DELIMITER​. En MySQL las sentencias se separan entre sí mediante el punto y


coma (;). Para poder escribir el procedimiento completo evitando que se ejecute al
encontrar el símbolo (;) tenemos que asignar la función de delimitador a otro carácter,
como por ejemplo la barra (|), como veremos en el siguiente ejemplo. Al finalizar,
asignamos al carácter punto y coma su función habitual.

Para ejecutar o llamar a un procedimiento, una vez creado, se usa la sentencia:

CALL NombreBaseDatos.NombreProcedimiento (lista_de_parámetros);

Estudiemos un ejemplo para comprender mejor toda esta información.


Imagina que en nuestra base de datos “Departamentos” se realiza a menudo una
consulta que solicita los empleados de un departamento que tienen un salario
superior a una cantidad concreta. Si sabemos que esta consulta suele utilizarse
regularmente, podemos guardarla como un procedimiento y cuando sea necesario
hacer una llamada al mismo pasándole los parámetros deseados, en este caso el
departamento y la cantidad correspondiente al salario límite.

El código necesario para este procedimiento sería el siguiente:

DELIMITER @
CREATE PROCEDURE EMPDPTO (
IN DPTO VARCHAR(50),
IN SALARIOLIMITE DECIMAL(10,2))
BEGIN
SELECT * FROM EMPLEADOS E, DEPARTAMENTOS D WHERE
NUMERODEPARTAMENTO = DEPARTAMENTO AND ​D.NOMBRE=DPTO AND
SALARIO>SALARIOLIMITE​;
END @
DELIMITER ;

Observa como es necesario un espacio en blanco entre la palabra


reservada DELIMITER y el propio delimitador.

Como el procedimiento espera dos parámetros, en la llamada es necesario


pasarle valores para estos parámetros y la sentencia SELECT debe utilizar estos
parámetros en la cláusula WHERE en lugar de literales (condiciones en rojo). Los tipos
de datos de los parámetros deben coincidir con los tipos de datos de los campos con
los que se van a comparar.

Finalmente, cambiamos el delimitador con “DELIMITER ;” y realizamos la llamada


mediante CALL.

5
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

CALL EMPDPTO (‘Nóminas’, 1000).

Las imágenes siguientes muestran la creación y posterior llamada a este


procedimiento. En la llamada, como puede observarse, se le pasan los valores
‘Nóminas’ y 1000, que coinciden en tipo y orden con los parámetros declarados en la
creación del procedimiento.

Los procedimientos al ser creados se guardan en el servidor, en la base de datos


actual y pueden ser llamados por el usuario que los creó y por cualquier otro con
autorización. ​En este punto debo avisar que la gestión de usuarios y permisos no
compete a este módulo.

Al crear un procedimiento, el servidor puede indicar errores que este pudiera tener.
En estos casos, el procedimiento no se crea. Será necesario corregir estos errores
para que el procedimiento se cree y se guarde en la base de datos.

Siempre podemos volver a visualizar el código de un procedimiento creado con la


sentencia SHOW CREATE PROCEDURE NombreProcedimiento.

Ejemplo 1. Procedimiento que recibe como parámetro de entrada (IN) un nombre


de departamento y devuelve el salario medio de los empleados de ese departamento
como parámetro de salida (OUT). Para cargar el valor en el parámetro de salida se
utiliza ​INTO variable​. Para que esto sea así, el procedimiento debe devolver una sola
fila.

6
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

DELIMITER @
CREATE PROCEDURE MEDIASALARIO (IN NOMBREDEP VARCHAR(50), OUT
MEDIA DECIMAL(10,2))
BEGIN
SELECT AVG(SALARIO) INTO MEDIA FROM EMPLEADOS E, DEPARTAMENTOS D
WHERE NUMERODEPARTAMENTO=DEPARTAMENTO AND
D.NOMBRE=NOMBREDEP;
END@
DELIMITER ;

La llamada podría ser de la siguiente forma:

CALL MEDIASALARIO ('NÓMINAS', @MEDIA);


SELECT @MEDIA;

Como el procedimiento devuelve un valor, necesitamos una variable de usuario


(@MEDIA) donde guardar el valor que devuelve el procedimiento. La sentencia
SELECT muestra el valor de la variable @MEDIA.

Variables locales​. En los procedimientos almacenados pueden utilizarse variables


locales. Estas tienen la particularidad de que sólo existen dentro del procedimiento y
mientras este se ejecuta, después se destruyen. Sólo son visibles dentro del bloque
BEGIN…END donde están declaradas y deben estar al comienzo de este bloque
antes de cualquier sentencia.

Ejemplo 2. Procedimiento que muestra los departamentos y el número de


empleados. Deben aparecer sólo los departamentos que tienen más empleados que el
de Nóminas. En este caso no son necesarios los parámetros, ya que el procedimiento
no necesita datos de entrada y no devuelve nada, sino que muestra los resultados.

El procedimiento necesita una variable local (NUMERO) donde guardar el número


de empleados del departamento de Nóminas, para luego comparar este valor con el
número de empleados (COUNT) de cada departamento.

A partir de ahora, no incluiré la sentencia DELIMITER en los ejemplos.

CREATE PROCEDURE DPTOCUENTAEMP ()


BEGIN
DECLARE NUMERO INT;

SELECT COUNT(*) INTO NUMERO FROM EMPLEADOS WHERE


DEPARTAMENTO = (SELECT NUMERODEPARTAMENTO FROM
DEPARTAMENTOS WHERE NOMBRE='NÓMINAS');

7
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

SELECT D.NOMBRE, COUNT(*) FROM DEPARTAMENTOS D, EMPLEADOS


E WHERE D.NUMERODEPARTAMENTO=E.DEPARTAMENTO GROUP BY
D.NOMBRE HAVING COUNT(*)>NUMERO;

END;

Como puede observarse, con la primera SELECT calculamos el número de


empleados del departamento de Nóminas y lo guardamos en la variable NUMERO.
Más tarde en la segunda SELECT comparamos el número de empleados de cada
departamento con esta variable: HAVING COUNT(*)>NUMERO.

La llamada sería: CALL DPTOCUENTAEMP();

3.2. Modificación y eliminación de procedimientos almacenados.

Para modificar un procedimiento almacenado se utiliza la sentencia ALTER


PROCEDURE con la sintaxis que se indica:

ALTER PROCEDURE Nombre [Características …].

Las características son las mismas que las comentadas en el punto 3.1 de esta
unidad.

Con esta sentencia sólo pueden cambiarse las características del procedimiento,
no podrán cambiarse ni los parámetros ni su código. Para cambiar estos últimos será
necesario eliminar el procedimiento y crearlo de nuevo.

La sentencia que permite eliminar un procedimiento es DROP PROCEDURE [IF


EXISTS] Nombre. La cláusula IF EXISTS se utiliza para evitar errores si el
procedimiento no existe.

4. Funciones.

Las funciones son un conjunto de instrucciones que tras ejecutarse devuelven un


único valor.
Son similares a los procedimientos en cuanto a su creación. También se guardan
en el servidor y pueden ser invocadas en cualquier momento desde un cliente. Por
otro lado, aportan la ventaja de que pueden ser llamadas desde sentencias SQL, cosa
que no sucedía con los procedimientos.

Características:

- Se utilizan para obtener (retornar) un único valor a través de una serie de


cálculos y/o búsquedas.
- Devuelven este valor mediante la sentencia RETURN. El tipo del dato devuelto
debe ser declarado en la función.
- Sólo trabajan con parámetros de entrada. No es necesario especificar IN.

8
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

- No pueden llevar sentencias SELECT que devuelvan filas de resultados a


menos que esta fila sea única y se carguen sus datos en variables.
- Para llamarlas se utiliza su nombre y entre paréntesis sus parámetros. No se
usa CALL.
- Pueden ser llamadas desde sentencias SELECT, INSERT, UPDATE y
DELETE.
- Mediante SHOW FUNCTION STATUS podemos ver las funciones asociadas a
una base de datos.

4.1. Creación de funciones.

Para crear una función se utiliza la siguiente sintaxis:

CREATE FUNCTION NombreFuncion ([Parametro1 [, Parametro2,..]])


RETURNS Tipo}
[características …]
BEGIN CuerpoDeLaFuncion END

La cláusula RETURNS Tipo indica el tipo de dato de retorno de la función. Es decir,


si devuelve int, double, etc.

En el cuerpo de la función debe incluirse de forma obligatoria una orden del tipo
RETURN expresión​, siendo esta expresión del mismo tipo de datos que el devuelto
por la función (el indicado en RETURNS).

Las características son similares a las comentadas con los procedimientos.

Ejemplo. Función que devuelve la media de los salarios de un departamento cuyo


nombre será pasado como parámetro.

CREATE FUNCTION MEDIASALARIODPTO (NOMBREDEP VARCHAR(50))


RETURNS DECIMAL(10,2)
BEGIN

DECLARE MEDIA DECIMAL(10,2);

SELECT AVG(SALARIO) INTO MEDIA FROM EMPLEADOS E,


DEPARTAMENTOS D WHERE
E.Departamento=D.NumeroDepartamento AND D.Nombre=NOMBREDEP;

RETURN MEDIA;

END

En el ejemplo se declara una variable local, MEDIA, que será la que almacene el
dato a devolver. Su tipo de datos coincide con el indicado en RETURNS. La sentencia
SELECT hace el cálculo y guarda el resultado en esta variable: INTO MEDIA.
Finalmente, se devuelve esta variable: RETURN MEDIA.

9
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

Observa las dos formas de hacer referencia al valor de retorno: RETURNS y


RETURN. El primero para indicar el tipo de dato devuelto y el segundo para
devolverlo.

Ejemplos de llamada:

- Muestra la media de los salarios del departamento de Nóminas.

SELECT MEDIASALARIODPTO(‘NOMINAS’).

- Media de los salarios de todos los departamentos.

SELECT NOMBRE, MEDIASALARIODPTO(NOMBRE) FROM DEPARTAMENTOS

4.2. Modificación y eliminación de funciones.

Para modificar/eliminar funciones se utilizan las mismas sentencias que las


comentadas con los procedimientos.

Para modificar: ALTER FUNCTION Nombre [Características …]. Sólo podrán


modificarse las características de la función.

Para eliminar: DROP FUNCTION [IF EXISTS] Nombre.

5. Estructuras de control

Podemos escribir procedimientos y funciones más potentes y versátiles utilizando


las estructuras de control que nos proporciona MariaDb/MySql. Estas estructuras
permiten ejecutar un grupo de sentencias en función de si se cumple o no una
condición, también permiten ejecutar una serie de sentencias un número de veces...

5.2. La sentencia IF

Con esta sentencia puede dirigirse la ejecución del programa hacia una u otra
dirección en función de una condición.
Su sintaxis:

IF Condición1 THEN Sentencias1


[ELSE Sentencias_Else] END IF;

Esta sentencia podemos interpretarla de la siguiente forma: si la condición1 se


cumple, se ejecutan las sentencias indicadas en Sentencias1. Si no, se ejecutan las
indicadas en Sentencias_Else;

La condición es una expresión en la que se comparan dos valores. Ejemplos:


valor > 1000, ciudad=’Sevilla’, etc.

Un ejemplo. Diseñar un procedimiento almacenado que consulte el salario de un


empleado cuyo número se pasará como parámetro. En caso de que el salario sea
inferior a 1000, incrementarlo un 10%. Si el salario es igual o superior a 1000
incrementarlo un 5%.

10
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

En el cuerpo del procedimiento debe localizarse el salario del empleado pasado


como parámetro, luego preguntar por su valor con IF y según sea la respuesta hacer
un UPDATE u otro.

CREATE PROCEDURE INCREMENTASALARIO (IN NUM_EMP INT)


BEGIN

DECLARE SALARIOEMP DECIMAL(10,2);

SELECT SALARIO INTO SALARIOEMP FROM EMPLEADOS WHERE


NUMEROEMPLEADO=NUM_EMP;

IF SALARIOEMP<1000 THEN
UPDATE EMPLEADOS SET SALARIO=SALARIO*1.10 WHERE
NumeroEmpleado=NUM_EMP;
ELSE
UPDATE EMPLEADOS SET SALARIO=SALARIO*1.05 WHERE
NumeroEmpleado=NUM_EMP;
END IF;

END;

La sentencia IF tiene una variante:

IF Condición1 THEN Sentencias1 [ELSEIF Condición2 THEN Sentencias2]


… [ELSE Sentencias_Else] END IF;

En este caso si la Condición1 no se cumple se evalúa la Condición2 y si se cumple


se ejecutan las Sentencias2. Los puntos suspensivos indican que esta cláusula puede
repetirse varias veces. Si ninguna de las condiciones se cumple se ejecuta la cláusula
ELSE.

Ejemplo. Diseñar una función que devuelva “Más de 1000”, “Justo 1000” o “Menos
de 1000” según el salario de un empleado que se reciba como parámetro esté en un
grupo o en otro.

CREATE FUNCTION LOSMILES (NUMERO_EMP INT)


RETURNS VARCHAR(15)
BEGIN

DECLARE SALA DECIMAL(10,2);

SELECT SALARIO INTO SALA FROM EMPLEADOS WHERE


NUMEROEMPLEADO=NUMERO_EMP;

IF SALA=1000 THEN RETURN "JUSTO 1000";


ELSEIF SALA>1000 THEN RETURN "MÁS DE 1000";
ELSE RETURN "MENOS DE 1000";
END IF;

11
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

END;

El proceso consiste en guardar el salario del empleado pasado como parámetro en


la variable SALA y preguntar por esta variable con un IF_ELSEIF.

Podría llamarse a esta función desde una sentencia SELECT como sigue. Para
cada fila de la tabla Empleados se hace una llamada.

SELECT NUMEROEMPLEADO, NOMBRE, SALARIO ,


LOSMILES(NUMEROEMPLEADO) FROM EMPLEADOS

5.3. La sentencia CASE

La sentencia CASE se utiliza para evaluar múltiples opciones a partir de una


expresión. Si el conjunto de valores a evaluar es grande, para evitar incluir varios
ELSEIF, puede utilizarse esta sentencia.

Sintaxis:

CASE Expresión WHEN Valor1 THEN Sentencias1


[WHEN Valor2 THEN Sentencias2]
……………………………
[WHEN ValorN THEN SentenciasN] [ELSE Sentencias_Else] END CASE;

Su funcionamiento es el siguiente, se evalúa la expresión y en función del valor


devuelto se ejecuta un grupo de sentencias u otro. Si devuelve Valor1 se ejecutan las
sentencias Sentencias1, si devuelve Valor2 las Sentencias2, y así sucesivamente. Si
la expresión devuelve un valor no contenido en la lista de valores, se ejecutan las
sentencias situadas tras ELSE.

Otra sintaxis:

CASE WHEN Condición1 THEN Sentencias1


[WHEN Condición2 THEN Sentencias2]
……………………………
[WHEN CondiciónN THEN SentenciasN]
ELSE Sentencias_Else END CASE;

En este caso pueden evaluarse varias condiciones y se ejecutan las instrucciones


correspondientes a la condición que se cumple.

Modificaremos el ejemplo anterior para hacerlo con CASE. Diseñar una función
que devuelva “Más de 1000”, “Justo 1000” o “Menos de 1000” según el salario de un
empleado que se reciba como parámetro esté en un grupo o en otro

CREATE FUNCTION LOSMILESCASE (NUMERO_EMP INT)


RETURNS VARCHAR(15)
BEGIN
DECLARE SALA DECIMAL(10,2);

12
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

DECLARE CADENA VARCHAR(15);

SELECT SALARIO INTO SALA FROM EMPLEADOS WHERE


NUMEROEMPLEADO=NUMERO_EMP;

CASE
WHEN SALA=1000 THEN SET CADENA= "JUSTO 1000";
WHEN SALA<1000 THEN SET CADENA= "MENOS DE 1000";
WHEN SALA>1000 THEN SET CADENA= "MÁS DE 1000";
ELSE SET CADENA="ERROR";
END CASE;

RETURN CADENA;
END;

La llamada podría ser la misma que en el caso anterior:

SELECT NUMEROEMPLEADO, NOMBRE, SALARIO ,


LOSMILESCASE(NUMEROEMPLEADO) FROM EMPLEADOS

5.4. La sentencia WHILE (mientras)

La sentencia WHILE permite repetir un conjunto de instrucciones mientras se


cumpla una determinada condición. Es lo que en programación se conoce como bucle.
Podemos verlo de la siguiente forma: “mientras que se cumpla la condición se
ejecutan las sentencias encerradas en el bucle”.

Su sintaxis:

WHILE condición DO
sentencias
END WHILE

Es muy importante que antes del bucle (antes del while) se lleve a cabo la
inicialización de la variable que controla dicho bucle. Además dentro de las sentencias
del bucle, esta variable debe modificarse para que dicho bucle termine y no se
convierta en un bucle sin fin.

Un ejemplo: diseñar un procedimiento almacenado que reciba como parámetro de


entrada un número de departamento y muestre los trabajadores de ese departamento
cuyo salario es 1000 euros, los que tienen un salario de 2000 euros, los que ganan
3000 euros y así hasta 10000 euros.

13
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

El procedimiento recibe como dato de entrada un número de departamento. Luego


inicializa la variable SALARIOE con 1000 y empieza el bucle. Se evalúa la condición
del bucle, si es verdadera se entra en el bucle. En la primera vuelta se muestran los
trabajadores de ese departamento que ganan 1000 euros. Más tarde se modifica el
valor de SALARIOE, que pasa a ser 2000. Se vuelve a evaluar la condición del bucle y
se muestran los empleados que ganan 2000 euros, y así hasta que SALARIOE tenga
el valor 10000, que será cuando el bucle finalice.

Una llamada al procedimiento podría ser: CALL Bucle2(2) y su salida sería la de la


imagen.

5.5. La sentencia REPEAT (repetir)

El funcionamiento es parecido al de WHILE, salvo que aquí se repiten las


sentencias ​hasta que se cumpla la condición. Se diferencia del anterior bucle en
que con REPEAT las sentencias se ejecutan al menos una vez, ya que la
comprobación de la condición se realiza al final del mismo.

14
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

Sintaxis:

REPEAT
sentencias
UNTIL condición
END REPEAT

El mismo ejemplo que en el apartado anterior pero con REPEAT.

CREATE PROCEDURE BUCLEREPEAT (IN NUMDEP INT)


BEGIN
DECLARE SALARIOE INT;
SET SALARIOE=1000;
REPEAT
SELECT CONCAT("EMPLEADOS QUE GANAN: ",SALARIOE) AS D​ESCRIPCION​;
SELECT * FROM EMPLEADOS WHERE SALARIO = SALARIOE AND
DEPARTAMENTO=NUMDEP;
SET SALARIOE=SALARIOE+1000;
UNTIL SALARIOE=10000
END REPEAT;
END;

5.6. La sentencia LOOP

Su sintaxis:

[Etiqueta_Inicio:] LOOP
Sentencias
END LOOP [Etiqueta_Fin];

Permite realizar un bucle repetitivo que no tiene ninguna condición de salida. Para
salir de un bucle LOOP es necesario incluir una sentencia de salida forzada: LEAVE,
con la sintaxis ​“LEAVE etiqueta”​.

Con la sentencia ​“ITERATE etiqueta” se lleva a cabo un salto a la etiqueta


indicada para reiniciar el bucle desde ahí.

El siguiente ejemplo muestra el funcionamiento de los bucles con LOOP.

El objetivo del procedimiento almacenado es el de mostrar en pantalla los nombres


de los meses del año. Para ello, se parte de una variable m con valor 0, por cada
vuelta que da el bucle se incrementa esta variable en una unidad, se evalúa con un
CASE y en función de su valor se imprime el nombre del mes asociado. Tras esto se
comprueba si se ha llegado al final (m=12); en caso afirmativo se sale del bucle con
“Leave Eti_Arriba;”. Si no se ha llegado al mes 12 se salta a la etiqueta con “Iterate
Eti_Arriba;”.

CREATE PROCEDURE Meses ()


BEGIN
declare m int;
declare nombreMes varchar(20);

15
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

set m=0;

Eti_Arriba: Loop
set m=m+1;
CASE m
WHEN 1 THEN set nombreMes="Enero";
WHEN 2 THEN set nombreMes="Febrero";
WHEN 3 THEN set nombreMes="Marzo";
WHEN 4 THEN set nombreMes="Abril";
WHEN 5 THEN set nombreMes="Mayo";
WHEN 6 THEN set nombreMes="Junio";
WHEN 7 THEN set nombreMes="Julio";
WHEN 8 THEN set nombreMes="Agosto";
WHEN 9 THEN set nombreMes="Septiembre";
WHEN 10 THEN set nombreMes="Octubre";
WHEN 11 THEN set nombreMes="Noviembre";
WHEN 12 THEN set nombreMes="Diciembre";
ELSE set nombreMes="ERROR";
END CASE;
select nombreMes;
if m=12 then leave Eti_Arriba;
end if;
ITERATE Eti_Arriba;
End Loop Eti_Arriba;
END;

6. Manipuladores de error

Cada sentencia SQL ejecutada en el servidor da lugar a un código de error. Si se


ha ejecutado correctamente, este código será 0, si ha habido algún problema se
obtiene un código numérico asociado al error producido.

Ejemplos de sentencias que provocan errores:


- Insertar una clave primaria duplicada.
- Borrar un registro de la tabla principal cuando tiene registros relacionados y no
está activado el borrado en cascada.
- Insertar un valor en un campo clave ajena que no existe en otra tabla como
clave principal.

Si una sentencia forma parte de un procedimiento o función y genera un error,


entonces se termina automáticamente la ejecución del procedimiento o función

Para solucionar estos problemas, MariaDB proporciona los “manipuladores de


errores o handlers”, cuya función es indicar cómo debe responder el servidor a estos
errores.

Para que todo esto se entienda mejor, estudiaremos un ejemplo.

16
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

Crearemos un procedimiento almacenado que reciba como parámetro un número


de empleado y un nombre. El procedimiento se encargará de insertar ese empleado
en la tabla “Empleados”.

Puede darse el caso de que el empleado a insertar tenga un número de empleado


que ya exista en la tabla, en ese caso se obtiene el error 1062 como se observa en la
imagen.

Con esta situación, debe declararse un manipulador de error que asocie este
código de error a una sentencia de tratamiento del mismo.

Es necesario, por tanto, conocer los códigos de error que van a ser tratados.
Puedes consultar los códigos de error de MariaDB desde esta web:
https://mariadb.com/kb/en/mariadb/mariadb-error-codes/​.

Los manipuladores de error pueden ser de tipo CONTINUE o EXIT. El de tipo


CONTINUE hace que prosiga la ejecución en la siguiente sentencia a aquella donde
se ha producido el error. Si el tipo es EXIT, el bloque de código termina donde se ha
producido el error y, por tanto, la rutina en la que se encuentra.

La sintaxis básica para declarar un manipulador de error sería:

DECLARE TipoManipulador HANDLER FOR CódigoError Begin Sentencias End;

El valor de TipoManipulador debe ser CONTINUE o EXIT.

CódigoError debe ser sustituido por el código de error que se quiere tratar.

Finalmente, entre Begin y End, se escriben las sentencias que se ejecutan para
tratar el error que se ha producido. Si es una única sentencia la que trata el error, no
es necesario escribir Begin End.

El código del ejemplo sería:

CREATE PROCEDURE NUEVO_EMPLEADO (IN NUMERO INT, IN NOM


VARCHAR(50))
BEGIN

DECLARE EXIT HANDLER FOR 1062


BEGIN
SELECT 'CLAVE PRINCIPAL DUPLICADA' as Mensaje;
END;

INSERT INTO EMPLEADOS (NUMEROEMPLEADO, NOMBRE) VALUES


(NUMERO, NOM);

END;

17
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

En la imagen puede observarse una llamada al procedimiento y la salida que se


obtendría.

7. Manejo de cursores

Un cursor es un objeto que apunta a las filas devueltas por una consulta, es decir,
está asociado a una sentencia SELECT. Esta característica permite manipular los
datos de cada fila de forma individual. Esto puede resultar interesante, ya que en
ocasiones será necesario aplicar un tratamientos distintos a las filas devueltas.

En MariaDB los cursores son de solo lectura y además siempre son leídos desde el
principio hacia el final, es decir, hacia delante.

La programación de cursores es una tarea compleja, que requiere conocer a fondo


el lenguaje SQL y además, tener nociones de programación.

El trabajo con cursores se lleva a cabo en cuatro partes:

- Declaración.
- Apertura
- Lectura
- Cierre.

Declaración​. Los cursores deben declararse mediante DECLARE, pero siempre


después de las variables. Su sintaxis:

DECLARE NombreCursor CURSOR FOR SELECT …;

La sentencia SELECT utilizada en el cursor no puede llevar INTO.

Apertura​. En esta fase es cuando se ejecuta la SELECT asociada al cursor, además


el cursor sitúa un puntero o apuntador a la primera fila arrojada por la consulta. La
sintaxis de apertura es:

OPEN nombreCursor;

Lectura​. Es en la lectura donde se accede a los datos de la fila indicada por el


apuntador, y se guardan en variables los valores de las columnas para su posterior
tratamiento. Si se vuelve a hacer una lectura se leerá la segunda fila, luego la tercera y
así sucesivamente. La lectura se hace con la sentencia FETCH, que tiene la siguiente
sixtaxis:

18
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

FETCH nombreCursor INTO variable1, variable2,…

Cada variable debe tener el mismo tipo de datos que la columna que se almacenará
en ella.

Como es lógico, el leer todos los registros devueltos por la SELECT necesita de una
estructura repetitiva (bucle). La sentencia FETCH debe incluirse dentro del bucle para
automatizar el tratamiento.

Para terminar estos bucles debe incluirse un manejador de error especial. Este error
se produce cuando se intenta leer una fila y ya no existen más datos que leer. Su
declaración sería:

DECLARE CONTINUE HANDLER FOR NOT FOUND SET FIN = 1;

Cierre​. Una vez leídos los datos debemos cerrar el cursor mediante la sentencia
CLOSE nombreCursor.

Ejemplo 1. Base de datos Oposiciones.


Diseñar un procedimiento almacenado que cree una tabla e inserte en ella los valores
DNI de opositor, nombre, media de sus notas y un comentario. Este comentario debe
ser:
- Todo aprobado. Si aprobó los tres exámenes.
- Exámenes suspensos: X, Y y Z. Según corresponda.

El procedimiento debe crear la tabla si no existe.

CREATE PROCEDURE GESNOTAS()


BEGIN

DECLARE DNII VARCHAR(40);


DECLARE NOMBREE VARCHAR(40);
DECLARE MEDIA DECIMAL(10,4);

DECLARE NOTA1 TINYINT;


DECLARE NOTA2 TINYINT;
DECLARE NOTA3 TINYINT;
DECLARE COMENTARIO VARCHAR(111);
DECLARE FIN INT DEFAULT 0;

/*El cursor debe declararse antes del Handler*/


DECLARE CUR_NOTAS CURSOR FOR SELECT DNI, NOMBRE, AVG(NOTA)
FROM OPOSITORES, notas WHERE DNI=DNIOPOSITOR GROUP BY DNI;

/*HANDLER PARA LEER CURSOR*/


DECLARE CONTINUE HANDLER FOR NOT FOUND SET FIN = 1;

/*CREAR LA TABLA SI NO EXISTE*/


CREATE TABLE IF NOT EXISTS DATOS_OPOSITOR (

19
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

DNI VARCHAR(20) Primary Key,


NOMBRE VARCHAR(50),
MEDIA DECIMAL(7,4),
COMENTARIO VARCHAR(100));

OPEN CUR_NOTAS;

RECORRE: LOOP
/*ACCEDEMOS A LAS FILAS*/
FETCH CUR_NOTAS INTO DNII, NOMBREE, MEDIA;

/*HEMOS ALCANZADO EL FINAL??*/


IF FIN THEN
LEAVE RECORRE;
END IF;

/*COMPROBAMOS CADA EXAMEN DE ESE opositor*/


SELECT NOTA INTO NOTA1 FROM NOTAS WHERE DNIOPOSITOR=DNII AND
CODIGOEXAMEN=1;
SELECT NOTA INTO NOTA2 FROM NOTAS WHERE DNIOPOSITOR=DNII AND
CODIGOEXAMEN=2;
SELECT NOTA INTO NOTA3 FROM NOTAS WHERE DNIOPOSITOR=DNII AND
CODIGOEXAMEN=3;

IF NOTA1>=5 AND NOTA2>=5 AND NOTA3>=5 THEN


SET COMENTARIO="TODO APROBADO";
ELSE
SET COMENTARIO="HA SUSPENDIDO LOS EXAMENES: " ;
IF NOTA1<5 THEN
SET COMENTARIO=concat(COMENTARIO, "1-");
END IF;
IF NOTA2<5 THEN
SET COMENTARIO=concat(COMENTARIO, "2-");
END IF;
IF NOTA3<5 THEN
SET COMENTARIO=concat(COMENTARIO, "3");
END IF;
END IF;

/*INSERTAMOS LA FILA*/
INSERT INTO DATOS_OPOSITOR (DNI, NOMBRE, MEDIA, COMENTARIO)
VALUES (DNII, NOMBREE, MEDIA, COMENTARIO);

SELECT DNII, NOMBREE, MEDIA, COMENTARIO;

END LOOP RECORRE;


CLOSE CUR_NOTAS;
END;

20
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

Las líneas que siguen muestran otra forma de resolver el mismo ejercicio, en este
caso utilizando un bucle WHILE en lugar de LOOP.

create procedure GestionNotasWhile ()


BEGIN

DECLARE DNII VARCHAR(40);


DECLARE NOMBREE VARCHAR(40);
DECLARE MEDIA DECIMAL(10,4);

DECLARE NOTA1 TINYINT;


DECLARE NOTA2 TINYINT;
DECLARE NOTA3 TINYINT;
DECLARE COMENTARIO VARCHAR(111);
DECLARE FIN INT DEFAULT 0;

/*El cursor debe declararse antes del Handler*/


DECLARE CUR_NOTAS CURSOR FOR SELECT DNI, NOMBRE, AVG(NOTA)
FROM OPOSITORES, notas WHERE DNI=DNIOPOSITOR GROUP BY DNI;

/*HANDLER PARA LEER CURSOS*/


DECLARE CONTINUE HANDLER FOR NOT FOUND SET FIN = 1;

/*CREAR LA TABLA SI NO EXISTE*/


CREATE TABLE IF NOT EXISTS DATOS_OPOSITOR2 (DNI VARCHAR(20)
primary key , NOMBRE VARCHAR(50), MEDIA DECIMAL(7,4), COMENTARIO
VARCHAR(100));

OPEN CUR_NOTAS;

/*ACCEDEMOS A LA 1ª FILA*/
FETCH CUR_NOTAS INTO DNII, NOMBREE, MEDIA;

WHILE FIN=0 DO

/*COMPROBAMOS CADA EXAMEN DE ESE opositor*/


SELECT NOTA INTO NOTA1 FROM NOTAS WHERE DNIOPOSITOR=DNII AND
CODIGOEXAMEN=1;
SELECT NOTA INTO NOTA2 FROM NOTAS WHERE DNIOPOSITOR=DNII AND
CODIGOEXAMEN=2;
SELECT NOTA INTO NOTA3 FROM NOTAS WHERE DNIOPOSITOR=DNII AND
CODIGOEXAMEN=3;

IF NOTA1>=5 AND NOTA2>=5 AND NOTA3>=5 THEN


SET COMENTARIO="TODO APROBADO";
ELSE
SET COMENTARIO="HA SUSPENDIDO LOS EXAMENES: " ;
IF NOTA1<5 THEN
SET COMENTARIO=concat(COMENTARIO, "1-");

21
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

END IF;
IF NOTA2<5 THEN
SET COMENTARIO=concat(COMENTARIO, "2-");
END IF;
IF NOTA3<5 THEN
SET COMENTARIO=concat(COMENTARIO, "3");
END IF;
END IF;

/*INSERTAMOS LA FILA*/
INSERT INTO DATOS_OPOSITOR2 (DNI, NOMBRE, MEDIA, COMENTARIO)
VALUES (DNII, NOMBREE, MEDIA, COMENTARIO);

SELECT DNII, NOMBREE, MEDIA, COMENTARIO;


//avanzamos otra fila
FETCH CUR_NOTAS INTO DNII, NOMBREE, MEDIA;

END WHILE;

CLOSE CUR_NOTAS;

END;

Ejemplo 2. Base de datos Departamentos.


Diseñar un procedimiento almacenado que actualice los salarios de los empleados de
los distintos departamentos de la forma que se indica a continuación.
- Si el departamento es el 1
o Si el salario es menor de 1000, incrementarlo un 5%.
o Si el salario está comprendido entre 1000 y 2000 euros, incrementarlo
un 3%.
o Si el salario es mayor que 2000 euros, incrementarlo un 1%.
- Para cualquier otro departamento incrementar el salario un 5%.

Aunque este ejemplo podríamos haberlo hecho sin cursor, nos servirá para su estudio.

CREATE PROCEDURE INCREMENTASALARIO2 ()


BEGIN

DECLARE NUMEROE INT;


DECLARE SALARIOO DECIMAL(8,2);
DECLARE DPTOO INT;
DECLARE INCREMENTO INT;
DECLARE FIN INT DEFAULT 0;

/*DECLAREMOS EL CURSOR QUE NOS DA ACCESO A LOS EMPLEADOS*/


DECLARE LISTAEMPLEADOS CURSOR FOR SELECT NUMEROEMPLEADO,
SALARIO, DEPARTAMENTO FROM EMPLEADOS;

/*EL MANIPULADOR PARA CONTROLAR EL FIN*/

22
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

DECLARE CONTINUE HANDLER FOR NOT FOUND SET FIN = 1;

/*ABRIMOS EL CURSOR*/
OPEN LISTAEMPLEADOS;

/*BUCLE PARA RECORRER EL CURSOR*/


RECORRE:LOOP

/*ACCEDEMOS A LAS FILAS, UNA A UNA*/


FETCH LISTAEMPLEADOS INTO NUMEROE, SALARIOO, DPTOO;

/*COMPROBAMOS SI HEMOS LLEGADO AL FIN*/


IF FIN=1 THEN
LEAVE RECORRE;
END IF;

/*PREGUNTAMOS POR EL DPTO*/


IF DPTOO=1 THEN
/*PREGUNTAMOS POR EL SALARIO Y ASIGNAMOS EL INCREMENTO*/
CASE
WHEN SALARIOO<1000 THEN SET INCREMENTO=5;
WHEN SALARIOO>=1000 AND SALARIOO<=2000 THEN SET
INCREMENTO=3;
WHEN SALARIOO>2000 THEN SET INCREMENTO=2;
ELSE SET INCREMENTO=0;
END CASE;
/*PARA CUALQUIER OTRO DPTO, EL INCREMENTO ES UN 5%*/
ELSE SET INCREMENTO=5;

END IF;

/*ACTUALIZAMOS*/
UPDATE EMPLEADOS SET SALARIO=SALARIO + (SALARIO*INCREMENTO)/100
WHERE NUMEROEMPLEADO=NUMEROE;

END LOOP RECORRE;

/*CERRAMOS EL CURSOR*/
CLOSE LISTAEMPLEADOS;

END; /*FIN DEL PROCEDURE.*/

23
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

8. Disparadores o Triggers.

Los procedimientos y funciones vistos hasta ahora permiten automatizar tareas,


pero se ponen en marcha gracias a la intervención del usuario.

Puede darse el caso de querer que se lleven a cabo acciones de forma automática,
cada vez que ocurre un determinado suceso. En estas situaciones son de gran utilidad
los​ disparadores o triggers​.

Podemos definir un trigger como una rutina o programa, asociado a una tabla, que
se pone en marcha cuando ocurre un determinado evento sobre la tabla en cuestión.
Estos eventos son las operaciones de inserción, eliminación o actualización (INSERT,
DELETE y UPDATE) sobre esta tabla.
Otros SGBD tienen una gran variedad de eventos que activan un trigger, pero en
MariaDb/MySQL estos solo se activan mediante las operaciones indicadas.

Para que se usan los triggers:

- Implementar restricciones definidas en el diseño de la base de datos y que no


se hayan podido llevar a cabo de otra forma (reglas de negocio).
- Implementar validación de datos
- Llamar a procedimientos almacenados si se produce un determinado evento.
- Replicar datos en otras tablas.
- Implementar registros y auditorías de tablas. Registrar en una tabla auxiliar
informaciones como cambios en otras tablas, ejecución de borrados o
actualizaciones, etc.

Se ha de tener en cuenta que:

- Un trigger se invoca antes o después de realizar una inserción, borrado o


actualización.
- Un trigger siempre está asociado a una tabla y sólo a una.
- Un trigger se ejecuta como parte de la transacción que lo activó.
- Los triggers se ejecutan de forma invisible para los clientes, por lo tanto, es
difícil determinar sus consecuencias.
- Los triggers pueden incrementar el trabajo del servidor.
- Puede existir más de un trigger asociado a la misma tabla.
- Una sentencia TRUNCATE no activa un disparador o trigger..
- Los triggers no pueden usar sentencias como COMMIT, ROLLBACK, START
TRANSACTION, LOCK/UNLOCK TABLES, ALTER, CREATE, DROP,
RENAME.
- No pueden existir varios triggers con el mismo nombre para una tabla.
- Para hacer referencia en un trigger a las columnas de la tabla que dispara el
trigger, no podemos usar normalmente el nombre de esa columna. Para ello
necesitamos los especificadores ​OLD y NEW que indican el valor de la
columna antes de la modificación que se trata de hacer y después de la
modificación respectivamente. La forma de usarlos es OLD.nombreColumna y
NEW.nombreColumna. Es necesario tener en cuenta que en un trigger
asociado a INSERT no puede usarse OLD, así como no puede usarse NEW en
un trigger asociado a DELETE.
- Hasta la versión 10.2.3 de MariaDB sólo se soportaba un trigger por evento.

24
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

Los eventos que activan los triggers son:

- BEFORE INSERT. Se activa antes de que los datos sean insertados.


- AFTER INSERT. Se activa después de que los datos sean insertados.
- BEFORE UPDATE. Se activa antes de que los datos sean actualizados.
- AFTER UPDATE. Se activa después de que los datos sean actualizados.
- BEFORE DELETE. Se activa antes de que los datos sean borrados.
- AFTER DELETE. Se activa después de que los datos sean borrados.

Para crear un trigger se usa la sentencia:

CREATE TRIGGER nombreTrigger


evento
ON nombreTabla
FOR EACH ROW
BEGIN
...
END;

Para dar nombre a los triggers se recomienda usar la forma:

nombreTrigger_nombreTabla_nombreEvento.

El evento puede ser cualquiera de los indicados anteriormente.

Las sentencias del trigger deben escribirse entre BEGIN…END;

FOR EACH ROW indica que el trigger se lanza por cada fila afectada por el evento. Es
decir, si se lleva a cabo un UPDATE que afecta a tres filas, el disparador se ejecuta
para cada una de ellas.

Veamos un ejemplo. Crearemos un trigger que se active después de hacer un


UPDATE en la tabla Empleados de la base de datos Departamentos. La función del
trigger será la de registrar en una tabla auxiliar los siguientes valores: número del
empleado asociado al UPDATE producido, fecha y hora del cambio, los valores del
salario antes y después de la actualización y el evento que generó el registro, en este
caso UPDATE. Si el campo salario no se alteró con el UPDATE los valores de salario
antes y después deben coincidir.

Para llevar a cabo esta tarea, antes, será necesario crear esa tabla auxiliar donde
guardar estos valores.

CREATE TABLE REGISTRO_CAMBIOS_EMPLEADOS (

ID INT AUTO_INCREMENT PRIMARY KEY,


NUMEROEMPLEADO INT,
FECHACAMBIO DATETIME,
SALARIOANTES DECIMAL(8,2),
SALARIODESPUES DECIMAL(8,2),
EVENTO VARCHAR(20)

25
IES Suárez de Figueroa- @vanza
Administración de sistemas informáticos en red
Gestión de bases de datos Unidad 6. Construcción de guiones

Ahora creamos el trigger.

CREATE TRIGGER TRIGGERCAMBIOEMP_EMPLEADOS_AFTERUPDATE


AFTER UPDATE
ON EMPLEADOS
FOR EACH ROW
BEGIN
/*VARIABLES QUE NECESITAREMOS*/
DECLARE NUMEE INT;
DECLARE INSTANTE DATETIME;

SET NUMEE = OLD.NUMEROEMPLEADO;


SET INSTANTE = CURDATE();

INSERT INTO REGISTRO_CAMBIOS_EMPLEADOS VALUES (DEFAULT,


NUMEE, INSTANTE, OLD.SALARIO, NEW.SALARIO, 'UPDATE');

END;

Para ver los disparadores de una base de datos o tabla disponemos de las
órdenes SHOW TRIGGERS y SHOW TRIGGERS FROM BaseDatos WHERE `Table`
= 'nombreTabla'.

La sentencia para eliminar un trigger es DROP TRIGGER nombreTrigger.

9. Para saber más​.

- https://mariadb.com/kb/en/stored-procedures/
- https://mariadb.com/kb/en/create-function/
- https://mariadb.com/kb/en/trigger-overview/
- ttps://www.javatpoint.com/mysql-trigger
- https://www.mysqltutorial.org/mysql-triggers.aspx/
- https://manuales.guebs.com/mysql-5.0/triggers.html

26

También podría gustarte