触发器是mysql数据库针对某张表发生增删改操时自动执行的一段语句集合,它是跟某张表关联绑定的,不像存储过程那种需要被动调用。触发器可以用来检验数据完整性,日志跟踪记录等。注意:不能在mysql本身系统数据库的表上创建触发器,要在其他数据库的表上创建。
创建触发器的结构:
create trigger trigger_name
before/after insert/update/delete
on table_name
for each row #行级触发器
begin
具体语句...
end
触发器针对的是数据库中表的每一行记录,每行数据在操作前后都会有一个对应的状态,触发器将没有操作之前的状态保存到 old 关键字中,将操作后的状态保存到 new 中
语法:old/new.字段名
需要注意的是,old 和 new 不是所有触发器都有
触发器类型 new和old的使用
INSERT型触发器 没有 old,只有 new,new 表示将要(插入前)或者已经增加(插入后)的数据
UPDATE型触发器 既有 old 也有 new,old 表示更新之前的数据,new 表示更新之后的数据
DELETE型触发器 没有 new,只有 old,old 表示将要(删除前)或者已经被删除(删除后)的数据
举例说明,在mysql里testdb数据库下的两个表,person以及person_log(是记录每次在person表里修改操作的日志)
mysql> use testdb;
mysql> show create table person\G;
*************************** 1. row ***************************
Table: person
Create Table: CREATE TABLE `person` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` text CHARACTER SET utf8,
`addr` text CHARACTER SET utf8,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
ERROR:
No query specified
mysql> show create table person_log\G;
*************************** 1. row ***************************
Table: person_log
Create Table: CREATE TABLE `person_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`operation` varchar(20) NOT NULL,
`optime` datetime NOT NULL,
`opinfo` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
1 row in set (0.01 sec)
先创建一个在delete操作后,发生的触发器person_delaft_trigger。这个触发器的作用,就是当在person表里删除记录后,在日志表person_log里插入一条记录,把删除的信息输入。
mysql> delimiter $
mysql> create trigger person_delaft_trigger after delete on person for each row insert into person_log(operation,optime,opinfo) values('delete',now(),concat('del row: ',old.name,' ',old.addr))$ #这里是delete操作,只有old关键字,记录的是删除的记录数据
刚开始的表数据:
当我们进行一个删除操作后:
可以看到在person_log日志表就有一条记录了。
下面,我们再创建2个触发器,分别是在insert操作之前和之后,通过show triggers\G;可以看到当前的所有触发器信息:
在插入之前的触发器,执行语句是:
if new.name='andy' then
set new.name='haha';
end if
意思是,如果name字段是andy,就改为haha。
在插入之后的触发器,执行语句是:
begin insert into person_log(operation,optime,opinfo) values('insert',now(),concat('new row: ',new.name,' ',new.addr)); end
因为是insert操作,所以是new关键字,代表的是新记录。
这个语句就是在person_log日志表里新建一条日志,把该条插入的数据写入。
测试执行下:
可以看到,我们连着插入两条数据记录在person表,第2条数据记录因为name字段是andy,所以会调用插入前的触发器,最终在表里实际插入的是haha。而插入后的触发器也执行了,在person_log表里插入了两条日志记录。
还有一个update更新的触发器,这里不再说明了,它是有old和new两个关键字,分别表示更新前的记录和更新后的记录。
最后,删除触发器指令:drop trigger 触发器名字,查看某个触发器信息:show create trigger 触发器名字\G,查看所有触发器信息:show triggers\G;