触发器:和存储过程一样也是能够完成特定功能的的sql片段,触发器不需要调用,当对数据表中的数据进行DML操作的时候会自动触发
DML:数据操纵语言,就是增删改查
学生表和日志信息表-- 学生表
- CREATE TABLE students(
- stunum INT PRIMARY KEY autoincrement,
- stuname VARCHAR(20) not NULL,
- stugender CHAR(2) not NULL,
- stu_age int not NULL
-
- );
-- 日志信息表:记录对学生信息的操作
- CREATE TABLE stulogs(
- id INT PRIMARY KEY autoincrement,
- time TIMESTAMP,
- logtext VARCHAR(200)
-
- );
即:当向student表添加学生的信息的时候,同时也要在日志表中添加一条操作日志,删除的时候也要添加一条日志的信息
也就是实现下面的操作,我往students表里面插入一条数据同时会触发触发器的操作往日志表中添加一条数据?
- INSERT INTO students (stunum,stuname,stugender,stuage) VALUES(1,'张三','男',20);
- INSERT INTO stulogs(time,log_text) VALUES(NOW(),'添加学生信息');
谁来这么做?当然是触发器,触发器会自动的帮忙执行这两句代码
什么操作才可以触发触发器?在MySQL中触发器只有执行insert,update,update才会触发触发器
案例的说明:学生表和日志表
学生信息表就算是记录学生的信息的
日志表是记录用户对学生信息表的操作记录的表
需求:当向学生表添加删除和更新数据的时候自动更新对日志表的数据
-- 如何创建触发器
-- 注意触发器名字后面不要()
CREATE TRIGGER tri1
-- 触发的时机 before|after 二选一
-- 定义DML的类型
FOR EACH ROW -- 声明为行级触发器,只要操作一条记录就会触发触发器并执行一次
BEGIN
END
CREATE TRIGGER tri2
AFTER
INSERT ON students
FOR EACH ROW
BEGIN
INSERT INTO stulogs(time,logtext) VALUES(NOW(),CONCAT('已添加',NEW.stunum,'学生信息'));
END
-- 查看所有的触发器
SHOW TRIGGERS;
-- 当成功执行下面的语句会自动的在日志文件中插入一条数据
INSERT INTO students (stunum,stuname,stugender,stuage) VALUES(3,'王五','男',20);
-- 删除触发器
DROP TRIGGER tri2;
-- new和old
触发器用于监听DML操作
在触发器中通常处理一些DML的关联操作
可以用new或old在触发器中获取触发这个触发器的DML数据
new用于获取insert操作添加的数据或者update修改后的记录
old用于获取delete删除前的或者update操作修改前的数据
也就是说new是获取最新的数据,old是获取旧的数据
总结:new只能监听insert和update事件,old可以监听old和update事件
-- 创建触发器
CREATE TRIGGER tri1
AFTER UPDATE ON students
FOR EACH ROW
BEGIN
-- 获取是触发后的新数据
INSERT INTO stulogs(time,logtext) VALUES(NOW(),CONCAT('修改学生信息为',NEW.stunum,NEW.stuname));
END
UPDATE students SET stuname='王五五' WHERE stu_num=3;
CREATE TRIGGER tri3
BEFORE UPDATE ON students
FOR EACH ROW
BEGIN
-- 获取是触发后的新数据
INSERT INTO stulogs(time,logtext) VALUES(NOW(),CONCAT('修改前学生信息为',old.stunum,old.stu_name));
END
UPDATE students SET stuname='王五六' WHERE stunum=3;
-- 记录删除前的信息
CREATE TRIGGER tri4
BEFORE DELETE ON students
FOR EACH ROW
BEGIN
INSERT INTO stulogs(time,logtext) VALUES(NOW(),CONCAT('删除前学生信息为',old.stunum,old.stu_name));
END
CREATE TRIGGER tri5
AFTER DELETE ON students
FOR EACH ROW
BEGIN
INSERT INTO stulogs(time,logtext) VALUES(NOW(),CONCAT('删除前学生信息为',old.stunum,old.stu_name));
END
DELETE FROM students WHERE stu_num=4;
-- 将某个信息改为某个信息
CREATE TRIGGER tri6
AFTER UPDATE ON students
FOR EACH ROW
BEGIN
INSERT INTO stulogs(time,logtext) VALUES(NOW(),CONCAT('将',old.stunum,old.stuname,'修改为',new.stunum,new.stu_name));
END;
UPDATE students SET stuname='陈大王' WHERE stunum=4;
DROP TRIGGER tri1;
DROP TRIGGER tri2;
DROP TRIGGER tri3;
DROP TRIGGER tri4;
DROP TRIGGER tri5;
DROP TRIGGER tri6;
BEFORE触发器是指触发器在所监视的触发事件执行之前激活,激活后执行的操作先于监视的事件,这样就有机会进行一些判断,或修改即将发生的操作。
BEFORE触发器也可以根据监视事件分为三种,分别是INSERT型、UPDATE型和DELETE型。
Before与After区别:
before:(insert、update)可以对new进行修改,after不能对new进行修改,三者都不能修改old数据。
总之before可以对插入和修改的数据进行修改,也就是可以对new的数据的进行修改,但是after不可以对new的数据进行修改,同样的before和after都不可以对old数据进行修改
使用的总结:
优点:触发器是自动执行的,有个特点只能通过DM操作进行触发
可以表的级联操作和关联操作,有利于保证数据的完整性
可以对DML的数据的提供更为复杂的合法性的校验
现在也是不常用了
缺点:
使用触发器实现的业务出现的错误难以定位后期维护困难
大量使用导致代码结构杂乱,增加程序的复杂性,执行的效率变低了
数据量大的时候效率非常低
在互联网的应用尽量不适用存储过程和触发器,不利于数据库的迁移