Disparador de MySQL
Prefacio
Este entorno se basa en el sistema Centos 7.8 para construir MySQL-5.7.14 para
una construcción específica, consulte la construcción del entorno MySQL-5.7.14
A menudo es necesario realizar una consulta de combinación en las tablas emp y dept, cada vez que se conectan las tablas y se escribe la misma cadena de declaraciones. Al mismo tiempo, debido a que los datos de la cola de sueldos son más confidenciales, los requisitos externos son no visible.
De esta forma, podemos completar creando una vista
1. ¿Qué es un disparador?
Trigger (desencadenador) es un procedimiento almacenado especial, su ejecución no es llamada por el programa, ni se inicia manualmente, sino que se desencadena por eventos.
Cuando se realiza una operación (insertar, eliminar, actualizar) en una tabla, se activará para su ejecución. Los activadores se utilizan a menudo para fortalecer las restricciones de integridad de los datos y las reglas comerciales.
Por ejemplo, cuando se agrega la información de un estudiante a la tabla de estudiantes, el número total de estudiantes debe cambiarse al mismo tiempo. Por lo tanto, se puede crear un disparador para la tabla de estudiantes, y cada vez que se agrega o elimina un registro de estudiante, se realiza una operación de cálculo del número total de estudiantes para asegurar la consistencia entre el número total de estudiantes y el número de registros.
El disparador (disparador) es un procedimiento almacenado especial, la diferencia es que la ejecución del procedimiento almacenado debe ser llamado por la instrucción CALL,
y la ejecución del disparador no necesita ser llamada por la instrucción CALL o iniciada manualmente, como mientrasCuando ocurre un evento predefinido, MySQL lo llamará automáticamente.
Las ventajas del programa de activación son las siguientes:
- La ejecución del programa de activación es automática. Se ejecutará inmediatamente después de realizar los cambios correspondientes a los datos de la tabla relacionada con el programa de activación.
- El disparador puede conectar en cascada y modificar otras tablas a través de tablas relacionadas en la base de datos.
- El programa de activación puede implementar comprobaciones y operaciones más complejas que las restricciones FOREIGN KEY y las restricciones CHECK.
2. Activar caso real
1. Varias tablas para estudiantes
Sincronización de información y nuevo (agregar, eliminar)
crear disparador
Prepare dos tablas: estudiante, estudiante_total.
Cuando se agrega o elimina información de estudiante en la tabla de estudiantes, las estadísticas de estudiante_total también se actualizan
# 创建student
mysql> create table student
-> (id int unsigned auto_increment primary key,
-> name varchar(50));
# 创建student_total
mysql> create table student_total(total int);
# 两张表中分别插入数据
mysql> insert into student(name) values('z3');
mysql> insert into student_total values(1);
mysql> select * from student;
+----+------+
| id | name |
+----+------+
| 1 | z3 |
+----+------+
1 row in set (0.00 sec)
mysql> select * from student_total;
+-------+
| total |
+-------+
| 1 |
+-------+
1 row in set (0.00 sec)
# 创建学生信息增加 触发器
mysql> \d $$
mysql> create trigger student_insert after insert
-> on student for each row
-> begin
-> update student_total set total=total+1;
-> end$$
mysql> \d ;
# 创建学生信息删除 触发器
mysql> \d $$
mysql> create trigger student_delete after delete
-> on student for each row
-> begin
-> update student_total set total=total-1;
-> end$$
mysql> \d ;
# 增加学生时
mysql> insert into student(name)
-> values('l4');
mysql> select * from student;
+----+------+
| id | name |
+----+------+
| 1 | z3 |
| 2 | l4 |
+----+------+
2 rows in set (0.00 sec)
mysql> select * from student_total;
+-------+
| total |
+-------+
| 2 |
+-------+
1 row in set (0.00 sec)
# 删除学生时
mysql> delete from student
-> where id=1;
mysql> select * from student;
+----+------+
| id | name |
+----+------+
| 2 | l4 |
+----+------+
1 row in set (0.00 sec)
mysql> select * from student_total;
+-------+
| total |
+-------+
| 1 |
+-------+
1 row in set (0.00 sec)
Ver el disparador creado
# 查看创建的触发器
mysql> show triggers\G
*************************** 1. row ***************************
Trigger: student_insert
Event: INSERT
Table: student
Statement: begin
update student_total set total=total+1;
end
Timing: AFTER
Created: 2021-02-03 15:05:38.49
sql_mode: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
Definer: root@localhost
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: utf8_general_ci
*************************** 2. row ***************************
Trigger: student_delete
Event: DELETE
Table: student
Statement: begin
update student_total set total=total-1;
end
Timing: AFTER
Created: 2021-02-03 15:21:11.06
sql_mode: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
Definer: root@localhost
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: utf8_general_ci
2 rows in set (0.00 sec)
mysql> select * from information_schema.triggers where TRIGGER_NAME='student_insert' or TRIGGER_NAME='student_delete'\G
*************************** 1. row ***************************
TRIGGER_CATALOG: def
TRIGGER_SCHEMA: db
TRIGGER_NAME: student_insert
EVENT_MANIPULATION: INSERT
EVENT_OBJECT_CATALOG: def
EVENT_OBJECT_SCHEMA: db
EVENT_OBJECT_TABLE: student
ACTION_ORDER: 1
ACTION_CONDITION: NULL
ACTION_STATEMENT: begin
update student_total set total=total+1;
end
ACTION_ORIENTATION: ROW
ACTION_TIMING: AFTER
ACTION_REFERENCE_OLD_TABLE: NULL
ACTION_REFERENCE_NEW_TABLE: NULL
ACTION_REFERENCE_OLD_ROW: OLD
ACTION_REFERENCE_NEW_ROW: NEW
CREATED: 2021-02-03 15:05:38.49
SQL_MODE: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
DEFINER: root@localhost
CHARACTER_SET_CLIENT: utf8
COLLATION_CONNECTION: utf8_general_ci
DATABASE_COLLATION: utf8_general_ci
*************************** 2. row ***************************
TRIGGER_CATALOG: def
TRIGGER_SCHEMA: db
TRIGGER_NAME: student_delete
EVENT_MANIPULATION: DELETE
EVENT_OBJECT_CATALOG: def
EVENT_OBJECT_SCHEMA: db
EVENT_OBJECT_TABLE: student
ACTION_ORDER: 1
ACTION_CONDITION: NULL
ACTION_STATEMENT: begin
update student_total set total=total-1;
end
ACTION_ORIENTATION: ROW
ACTION_TIMING: AFTER
ACTION_REFERENCE_OLD_TABLE: NULL
ACTION_REFERENCE_NEW_TABLE: NULL
ACTION_REFERENCE_OLD_ROW: OLD
ACTION_REFERENCE_NEW_ROW: NEW
CREATED: 2021-02-03 15:21:11.06
SQL_MODE: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
DEFINER: root@localhost
CHARACTER_SET_CLIENT: utf8
COLLATION_CONNECTION: utf8_general_ci
DATABASE_COLLATION: utf8_general_ci
2 rows in set (0.00 sec)
Eliminar disparador
mysql> drop trigger student_insert;
Query OK, 0 rows affected (0.00 sec)
mysql> drop trigger student_delete;
Query OK, 0 rows affected (0.00 sec)
mysql> show triggers\G
Empty set (0.00 sec)
2. Actualización sincrónica de información de varias tablas (agregar, actualizar, eliminar)
# 创建tb1、tb2表
mysql> create table tb1
-> (id int primary key auto_increment,
-> name varchar(50),
-> gender enum('男','女') default '男',
-> age int);
mysql> create table tb2
-> (id int primary key auto_increment,
-> name varchar(50),
-> salary double(10,2)
-> );
# 分别创建插入、更新、删除的触发器
mysql> create trigger tb1_after_insert
-> after insert
-> on tb1 for each row
-> begin
-> insert into tb2(name,salary) values(new.name,8000);
-> end$$
mysql> create trigger tb1_after_update
-> after update
-> on tb1 for each row
-> begin
-> update tb2 set name=new.name where name=old.name;
-> end$$
mysql> create trigger tb1_after_delete
-> after delete
-> on tb1 for each row
-> begin
-> delete from tb2 where name=old.name;
-> end$$
#
# 测试
---tb1插入三条记录
mysql> insert into tb1(name,age) values('张三','16');
mysql> insert into tb1(name,age) values('李四','22');
mysql> insert into tb1(name,age) values('王五','32');
---tb1、tb2均插入信息
mysql> select * from tb1;
+----+--------+--------+------+
| id | name | gender | age |
+----+--------+--------+------+
| 1 | 张三 | 男 | 16 |
| 2 | 李四 | 男 | 22 |
| 3 | 王五 | 男 | 32 |
+----+--------+--------+------+
3 rows in set (0.00 sec)
mysql> select * from tb2;
+----+--------+---------+
| id | name | salary |
+----+--------+---------+
| 1 | 张三 | 8000.00 |
| 2 | 李四 | 8000.00 |
| 3 | 王五 | 8000.00 |
+----+--------+---------+
3 rows in set (0.00 sec)
# 修改id=2的学生name
mysql> update tb1
-> set name='老六'
-> where id=2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from tb1;
+----+--------+--------+------+
| id | name | gender | age |
+----+--------+--------+------+
| 1 | 张三 | 男 | 16 |
| 2 | 老六 | 男 | 22 |
| 3 | 王五 | 男 | 32 |
+----+--------+--------+------+
3 rows in set (0.00 sec)
mysql> select * from tb2;
+----+--------+---------+
| id | name | salary |
+----+--------+---------+
| 1 | 张三 | 8000.00 |
| 2 | 老六 | 8000.00 |
| 3 | 王五 | 8000.00 |
+----+--------+---------+
3 rows in set (0.00 sec)
mysql> delete from tb1
-> where id=3;
Query OK, 1 row affected (0.00 sec)
mysql> select * from tb1;
+----+--------+--------+------+
| id | name | gender | age |
+----+--------+--------+------+
| 1 | 张三 | 男 | 16 |
| 2 | 老六 | 男 | 22 |
+----+--------+--------+------+
2 rows in set (0.01 sec)
mysql> select * from tb2;
+----+--------+---------+
| id | name | salary |
+----+--------+---------+
| 1 | 张三 | 8000.00 |
| 2 | 老六 | 8000.00 |
+----+--------+---------+
2 rows in set (0.00 sec)