首页 > 技术文章 > MySql学习笔记——触发器

black-spike 2017-10-01 18:44 原文

今天又学习了一下mysql触发器的相关知识,对此做了一些笔记和总结。

定义及作用

触发器是一个被指定关联到一个表的数据对象,触发器不需要调用,当对一个表的特别事件出现时,它就会被激活。触发器的代码也是由声明式和过程式SQL语句组成,因此用在存储过程中的语句也可以用在触发器的定义中。
触发器的作用如下:

  • 触发器与表的关系密切,用于保护表中的数据。
  • 利用触发器可以方便的实现数据库中数据的完整性。

创建触发器

创建触发器使用CREATE TRIGGER语句,若要查看数据库中的触发器,可以使用SHOW TRIGGERS命令。
创建触发器的语法格式如下:

CREATE TRIGGER trigger_name  trigger_time trigger_event  ON tb1_name FOR EACH ROW trigger_stmt

说明:

  • trigger_name:触发器的名称,触发器在当前的数据库中必须具有唯一的名称,如果要在某个特定的数据库中创建,名称前面要加上数据库的名称。

  • trigger_time:触发器触发的时刻,有两个选项:AFTER和BEFORE,以代表触发器是在激活它的语句之前或之后触发。如果想要在激活触发器的语句执行之后执行几个或更多的改变,通常使用AFTER选项;如果想要验证新数据是否满足使用的限制,则使用BEFORE选项。

  • trigger_event:触发事件,指明了激活触发程序的语句类型。触发事件可以是以下情况:
    INSERT:将新行插入表时激活触发器。例如,通过INSERT,LOAD DATA和REPLACE语句。
    UPDATE:更改某行数据时激活触发器。例如,通过UPDATE语句。
    DALETE:从表中删除一行时激活触发器。例如。通过DELETE和REPLACE语句。

  • tb1_name:与触发器相关的表名,在该表上发生触发事件时才会激活触发器。同一个表中不能拥有两个具有相同触发时刻和事件的触发器。

  • FOR EACH ROW:这个声明用来指定,对于受触发事件影响的每一行都要激活触发器的动作。

  • trigger_stmt:触发器动作,包含触发器激活时将要执行的语句。如果要执行多个语句,可以使用BEGIN...END复合语句结构。这样,就能使用存储过程允许的相同语句。

  • 一张表中最多可以创建6个触发器,时间(BEFORE,AFTER)对类型(INSERT、UPDATE、DELETE)。

注意:触发器不能返回任何的结果到客户端,为了阻止从触发器返回结果,还要在触发器定义中包含SELECT语句。同样,也不能调用将数据返回客户端的存储过程。

例子:在user表中新增一条数据时,同时在与之关联的另外一张表中插入一条数据。

delimiter $$
create trigger useupdate after insert on user for each row 
begin 
 insert into questionnaire values(1,'1','1',1);
end $$
delimiter ;

insert into user values (19,'aa','bb','cc','dd','ff');

结果如图:

删除触发器

语法格式:

DROP TRIGGER [schema_name]trigger_name

说明:

  • trigger_name:指要删除的触发器名称。
  • schema_name为所在数据库的名称,如果是当前数据库,可以省略。

例子:

drop trigger useupdate;

修改触发器

不能直接修改触发器,要先删除后新增。

触发器记录

不管是否触发,只要当某种操作准备执行,系统就会将当前要操作的记录的当前状态和即将执行之后新的状态分别保留下来,供触发器使用。其中,操作的当前状态保存到old中,操作之后的新状态保存到new中。

  • old代表旧记录,new 代表新记录;
  • 删除之后没有new的,插入的时候没有old。
  • old和new 代表记录本身。
  • 对于INSERT语句,只有NEW 是合法的;对于DELETE语句,只有old才合法;而UPDATE语句可以与NEW和OLD同时使用。

使用方式:
old.字段名/new.字段名。

例子:删除一个用户时,同时删除与用户关联的另外一张表中的信息。由于删除用户时,用户的id可以已经删除了,所以使用old。

delimiter $$
create trigger userdelete after delete on user for each row 
begin 
 delete from questionnaire where id = old.id;
end $$
delimiter ;

delete from user where id = '19';

我只添加了一条数据用于演示,所以执行完后,数据是空的。

总结

其实,触发器很好理解,就是在一个动作发生时,又有另一个动作在发生,只是时机有所不同。

推荐阅读