Un trigger (o disparador) en una Base de datos, es un procedimiento que se ejecuta cuando se cumple una condición establecida al realizar una operación. en MySQL los triggers pueden procesar eventos en determinados momentos:
A continuación mostramos la lista de eventos que podemos disparar en determinado momento:
INSERT
)UPDATE
)DELETE
)A su vez podemos procesar estos eventos en dos momentos:
BEFORE
AFTER
En otras palabras podemos atrapar 3 eventos en 2 momentos por cada tabla en nuestra base de datos.
1 CREATE TRIGGER nombre_disp
2 momento_disp evento_disp ON nombre_tabla
3 FOR EACH ROW sentencia_disp;
El disparador queda asociado a la tabla nombre_tabla. Esta debe ser una tabla permanente, no puede ser una tabla TEMPORARY ni una vista.
momento_disp es el momento en que el disparador entra en acción. Puede ser BEFORE (antes) o AFTER (después), para indicar que el disparador se ejecute antes o después que la sentencia que lo activa.
sentencia_disp es la sentencia que se ejecuta cuando se activa el disparador.
1 DROP TRIGGER nombre_disp;
La sentencia DROP TRIGGER necesita que se posea el privilegio SUPER.
1 SHOW TRIGGERS;
Si se desean ejecutar múltiples sentencias, deben colocarse entre BEGIN ... END, el constructor de sentencias compuestas.
Para esto es necesario modifcar el delimitador de fin de instrucción (DELIMITER
) y al final restaurar por el delimitador por defecto ;
.
1 DELIMITER |
2 CREATE TRIGGER testref BEFORE INSERT ON test1
3 FOR EACH ROW BEGIN
4 INSERT INTO test2 SET a2 = NEW.a1;
5 DELETE FROM test3 WHERE a3 = NEW.a1;
6 UPDATE test4 SET b4 = b4 + 1 WHERE a4 = NEW.a1;
7 END
8 |
9 DELIMITER ;
No puede haber dos disparadores en una misma tabla que correspondan al mismo momento y sentencia. Por ejemplo, no se pueden tener dos disparadores BEFORE UPDATE. Pero sí es posible tener los disparadores BEFORE UPDATE y BEFORE INSERT o BEFORE UPDATE y AFTER UPDATE.
Vamos a crear una base de datos con el nombre prueba_triggers
, y nos seleccionamos para usar dicha base de datos, como se muestra a continuación:
1 CREATE DATABASE prueba_triggers;
2 USE prueba_triggers;
Posteriormente creamos dos tablas: alumnos y logs, donde en alumnos vamos a agregar un conjunto de disparadores que van a guardar registros en la tabla logs:
1 -- Borramos(si existe) y Creamos tabla alumnos
2 DROP TABLE IF EXISTS alumnos;
3 CREATE TABLE alumnos(
4 id INT(3)
5 PRIMARY KEY NOT
6 NULL AUTO_INCREMENT,
7 equipo INT(2),
8 nombre VARCHAR(150),
9 fecha_registro DATETIME
10 );
11
12 -- Borramos(si existe) y creamos la tabla logs para guardar
13 -- los eventos de la tabla
14 DROP TABLE IF EXISTS logs;
15 CREATE TABLE logs(
16 id INT(5)
17 PRIMARY KEY NOT NULL
18 AUTO_INCREMENT,
19 msg VARCHAR(200)
20 );
BEFORE INSERT
Vamos a crear un disparador que se va a encargar en generar la fecha de registro al agregar(insert) un nuevo alumno, ademas agregamos un registro en la tabla logs indicando que se va a guardar un determinado alumno:
1 -- Borramos el disparador si es que existe
2 DROP TRIGGER IF EXISTS auto_gen_fecha_reg;
3 -- Cambiamos el delimitador
4 delimiter //
5 CREATE TRIGGER auto_gen_fecha_reg
6 BEFORE INSERT ON alumnos
7 FOR EACH ROW
8 BEGIN
9 SET NEW.fecha_registro = (SELECT NOW());
10 SET NEW.equipo = (SELECT ROUND(RAND()*3));
11 INSERT INTO logs VALUES(
12 NULL,
13 CONCAT('Previo a guardar alumno: ', NEW.nombre)
14 );
15 END;//
16 delimiter ;
AFTER INSERT
Vamos a crear un disparador que se va a encargar agregar un registro en la tabla logs indicando que se guardo un determinado alumno:
1 -- Borramos el disparador si es que existe
2 DROP TRIGGER IF EXISTS despues_de_add_user;
3 -- Cambiamos el delimitador
4 delimiter //
5 CREATE TRIGGER despues_de_add_user
6 AFTER INSERT ON alumnos
7 FOR EACH ROW
8 BEGIN
9 INSERT INTO logs VALUES(
10 NULL,
11 CONCAT('Despues de guardar alumno: ', NEW.nombre)
12 );
13 END;//
14 delimiter ;
AFTER UPDATE
De forma análoga podemos agregar los disparadores after update
y el after delete
, como se muestra a continuación:
1 -- Borramos el disparador si es que existe
2 DROP TRIGGER IF EXISTS despues_de_edit_user;
3
4 -- Cambiamos el delimitador
5 delimiter //
6 CREATE TRIGGER despues_de_edit_user
7 AFTER UPDATE ON alumnos
8 FOR EACH ROW BEGIN
9 INSERT INTO logs VALUES(
10 NULL,
11 CONCAT(
12 'Se modifico el usuario: ', OLD.nombre
13 ,' Su nuevo nombre es:', NEW.nombre
14 )
15 );
16 END;//
17 delimiter ;
AFTER DELETE
1 -- Borramos el disparador si es que existe
2 DROP TRIGGER IF EXISTS borrando_alumno;
3
4 -- Cambiamos el delimitador
5 delimiter //
6 CREATE TRIGGER borrando_alumno
7 AFTER DELETE ON alumnos
8 FOR EACH ROW BEGIN
9 INSERT INTO logs VALUES(
10 NULL,
11 CONCAT('Se a borrado el alumno: ', OLD.nombre)
12 );
13 END;//
14 delimiter ;
A continuación veremos a ver algunas otras cosas que podemos hacer con los disparadores.
Una señal (SIGNAL) es una forma de regresar un "error" al motor de MySQL, este error lo podemos manejar por medio de:
Usted puede ocupar el SQLSTATE
con el valor '45000'
para generar un error genérico, esto resulta muy útil en el momento de querer alterar el comportamiento del motor de MySQL como lo vamos a ver a continuación:
Nota: El lector puede abundar mas en el tema: http://dev.mysql.com/doc/refman/5.5/en/signal.html
Vamos a agregar un disparador que al modificar un alumno valide que el campo nombre no sea menor a 6 caracteres, en caso contrario vamos a generar un error genérico (SQLSTATE 45000
) y vamos a generar un mensaje para informar al cliente o a nuestra aplicación el motivo del error:
1 CREATE TRIGGER antes_de_edit_user
2 AFTER UPDATE ON alumnos
3 FOR EACH ROW
4 BEGIN
5 SET @tam_nombre = LENGTH(NEW.nombre);
6 IF @tam_nombre < 6
7 THEN
8 SIGNAL SQLSTATE '45000';
9 SET @MESSAGE_TEXT = 'El nombre no puede ser menor a 6 caracteres';
10 END IF;
11 END
De esta forma impedimos que se inserten valores no deseados y/o que no comparten la lógica deseada a la vez que generamos un mecanismo para detectar este tipo de errores para poderlos manejar desde nuestra aplicación en cuestión.
Table of Contents | t |
---|---|
Exposé | ESC |
Full screen slides | e |
Presenter View | p |
Source Files | s |
Slide Numbers | n |
Toggle screen blanking | b |
Show/hide slide context | c |
Notes | 2 |
Help | h |