触发器,其实其作用就是名字所体现的作用,因某些条件而触发然后执行某个程序。
MYSQL5.0.2版本开始支持触发器。而MYSQL的触发器和存储过程一i杨,就是嵌入到MYSQL服务器的一段程序。
触发器是由某个条件或事件触发的,比如插入,更新,删除事件。所谓的事件就是指用户动作或者触发某个条件的行为。而这个触发器就是有点像是监听其它事件的感觉,定义好触发器后,其调用不需要用户操作了,而服务器会根据触发的条件进行操作。
触发器TRIGGER是一种与表操作有关的数据库对象.
创建触发器
格式如下:
CREATE TRIGGER 触发器的名
{BEFORE|AFTER}{INSERT|UPDATE|DELETE} ON 表名
FOR EACH ROW
触发器后执行的模块;
-
表名:表示触发器监控的对象。
-
BEFORE|ALTER:表示触发的后面条件的时间,BEFORE是触发器,ALTER表示触发后。
-
INSERT|UPDATE|DELETE: 触发的事件或称为条件为插入更新和删除数据。
- 触发器后执行的模块:可以是单个SQL,也可以是BEGIN…END结构组成的复合语句块。
这个地方又要补充两个神奇的关键字:NEW和OLD
这两个关键字,具体如何用在后面的案例中演示。
案例1
# 首先创建两个表
CREATE TABLE test_a(
t_id INT,
t_name VARCHAR(20)
);
CREATE TABLE test_b(
t_flag VARCHAR(20)
);
# 然后创建一个 触发器如果插入test_a数据就在test_b处插入 INSERT INTO test_b VALUES ('插入测试');
DELIMITER $
CREATE TRIGGER trigger_name
AFTER INSERT ON test_a
FOR EACH ROW
BEGIN
INSERT INTO test_b VALUES ('插入测试');
END $
DELIMITER ;
这个不需要调用,而是通过触发触发器的条件即可。
INSERT INTO test_a VALUES (1,'张三');
然后test_a插入了数据不再查看,而直接查询test_b表中的数据。
SELECT * FROM test_b;
案例2
# 还是案例1 但是用上NEW关键字
DELIMITER $
CREATE TRIGGER trigger_name1
AFTER INSERT ON test_a
FOR EACH ROW
BEGIN
INSERT INTO test_b VALUES (new.t_name);
END $
DELIMITER ;
# 插入数据
INSERT INTO test_a VALUES (2,'李四');
#现在查看数据
SELECT * FROM test_b;
可以看出NEW类似于将要插入的数据包装称一个对象,然后可以通过字段名取出值。
案例3
# 创建一个新表
CREATE TABLE test_c(
t_id INT,
t_name VARCHAR(20),
t_flag VARCHAR(20)
);
# 然后创建一个触发器 更新 test_a的数据,然后将前后数据插入test_c
DELIMITER $
CREATE TRIGGER trigger_name2
BEFORE UPDATE ON test_a
FOR EACH ROW
BEGIN
INSERT INTO test_c VALUES (old.t_id,old.t_name,'更新前');
INSERT INTO test_c VALUES (new.t_id,new.t_name,'更新后');
END $
DELIMITER ;
# 更新数据
UPDATE test_c SET t_id='10' WHERE t_name='李四';
# 查看数据
SELECT * FROM test_c;
现在看一下test_a的内容。
SELECT * FROM test_a;
前面更新是一条,那么现在更新所有的数据呢?
UPDATE test_a SET t_name='王五' ;
# 然后看test_c表中数据
可以看出如果更新数据全部也会每行进行触发。
当然触发器还可以有些逻辑在里面,比如触发后就不再执行sql等.
查看和删除触发器
查看触发器
查看触发器是查看在数据库种已存在的触发器的定义,状态和语法信息等
# 方式1
SHOW TRIGGERS;
# 方式2
SHOW CREATE TRIGGER 触发器名;
# 例子
SHOW CREATE TRIGGER trigger_name2;
# 方式3
SELECT * FROM information_schema.TRIGGERS [WHERE TRIGGER_NAME='触发器名']# 如果不带WHERE条件就查询所有的触发器
# 例子
SELECT * FROM information_schema.TRIGGERS WHERE TRIGGER_name='trigger_name1'
删除触发器
删除触发器,
DROP TRIGGER [IF EXISTS] 触发器名;
优缺点
优点
-
触发器可以确保数据的完整性,或者说是可以写好逻辑,防止自己忘了其它的操作.
- 比如两个表,插入这个表,然后在另一个表种再插入有关的数据,如果有触发器就可以避免自己忘记这个操作.
- 触发器还可以记录操作日志.
-
触发器再操作数据前,可以数据进行合法性的检查.
避免自己自己再插入数据的时候插入了非法数据或者不合理的数据.
缺点
-
触发器可读性很差,这个与存储过程,函数一样.
-
相关数据的变更,可能会东芝触发器出错.
因为触发器建立在表上,如果表的结构变更了,就会导致触发器出错,进而影响数据操作的正常运行.而且触发器本身就具有隐蔽性,出错的时候很难排查.
补充
如果在子表中定义外键约束,并且外键指定了ON UPDATE/DELETE CASCADE/SET NULL 子句,此事修改附表被引用的键值或删除父表被引用的记录时,也会引起子表的修改和删除操作.但是基于子表的UPDATE和DELETE语句定义的触发器不会被激活.