• 猎八哥浅谈MYSQL触发器


    博客出处:http://www.cnblogs.com/liebagefly/p/7517998.html

    什么是MYSQL触发器,我们先了解一下触发的意思。触发的字面意思是指因触动而激发起某种反应。

    MYSQL必知必会中对触发器的解释是:MySQL响应以下任意语句而自动执行的一条或多条MySQL语句(或位于 BEGIN 和 END 语句之间的一组语句)。其中以下任意语句是指:delete,insert,update。

    我对mysql中触发器的理解是mysql数据库的数据内容造成改变时(增加、删除、添加)执行的一个行为。

    特别注意:当你进行查询数据时无法调动触发器(我的理解是此时数据库中的内容无法发生改变调用触发器没有意义,因为触发器的作用是进行了数据库的备份,保证安全性等)。触发器被调动后所执行的行为(或者说是MySQL语句)中有增加、删除、添加。

    触发器的作用和意义:数据备份,数据同步,保证安全性。具体请看以下几种案例。SHOW TRIGGERS; 查看表中所有触发器。

    1.案例一,使用触发器用来数据备份。

    场景:在学生表中,在删除id为3的学生信息之前时,将这条要删除的信息插入到studentbackup表中,用来做备份。执行delete时产生触发行为。具体代码如下(有解析)。

    学生表
    CREATE TABLE `student` (
      `id` int(11) NOT NULL,
      `name` varchar(255) DEFAULT NULL,
      `zongfen` int(255) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=gbk
    学生备份表
    CREATE TABLE `studentbackup` (
      `id` int(11) NOT NULL,
      `name` varchar(255) DEFAULT NULL,
      `zongfen` int(255) DEFAULT NULL,
        deletetime datetime, 
      PRIMARY KEY (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=gbk
    
    创建触发器
    CREATE trigger deletestudent before delete on student
    for each ROW
    begin 
        insert into studentbackup (id,name,zongfen,deletetime)
    values(OLD.id,OLD.name,OLD.zongfen,NOW());
    end;

    解释:
    CREATE trigger deletestudent是指创建一个名为deletestudent的触发器,由于是在执行之前做备份所以此处使用before,

    delete on student是指student执行delete行为时有触发行为,
    for each row的汉语意思是每一行,用在这里表示当每一行受到影响时,触发器都会被启动,

    begin,end是触发器开始和结束的标记,

    begin和end之间的语句是触发器被调动后所执行的行为,这里新增了一个字段deletetime,它用来记录删除时间,有关mysql中时间的调取方法我会在其他博客中做详细说明。

    执行删除语句

    delete from student where id=3;

    执行完这条delete后,我们会发现学生表的一条信息被删除,而这条删除的信息在备份表中被插入。

     删除一条信息前后两表的信息

    删除之前

    删除之后

     2.案例二,使用触发器用来数据同步。

     场景:在学生表中有四条信息,学生1表中有四条相同的信息,当学生表中插入一条信息时,学生1表中会产生一条相同的新的信息(即学生表1和学生表的信息均相同)。执行insert时产生触发行为。

    学生表1
    CREATE TABLE `student1` ( `id` int(11) NOT NULL, `name` varchar(255) DEFAULT NULL, `zongfen` int(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=gbk

    创建触发器
    CREATE trigger insertstudent after insert on student
    for each ROW
    begin 
        insert into student1 (id,name,zongfen)
    values(new.id,new.name,new.zongfen);
    end;

    执行插入语句

    insert into student (id,name,zongfen) values(5,'e',195);

    插入前后两表内容:

    插入之前

    插入之后

      

    3.案例三:使用触发器用来数据备份和同步。

    更改学生表的信息,这个情况比案例一和案例二都较为复杂。因为当进行学生表信息更新时,在更改之前要将信息进行备份,更改之后要将更改后的信息更新到同步表中。话不多说直接上代码。

    在更新之前将数据备份
    CREATE
    trigger updatestudent before update on student for each ROW begin insert into studentbackup (id,name,zongfen,deletetime) values(old.id,old.name,old.zongfen,NOW()); end; 更新之后将数据同步到同步表中,备注一下:我们暂不考虑更新时更改id这种行为,
    因为id没有改变,所以这里where id = old.id;或者where id = new.id;均正确,
    CREATE trigger updatestudent1 after update on student
    for each ROW
    begin 
        UPDATE student1 set name = new.name,zongfen = new.zongfen
            where id = old.id;
    end;

    执行更新语句
    UPDATE student set name = 'z',zongfen = 100 where id = 4;

    数据更新前后:

    更新之前

    更新之后

     

     :4.案例四:将学生表中成绩最高的学生信息,导入到maxgrade中去。话不多说,直接上代码。

    begin 
        DELETE from maxgrade;
        select max(zongfen) into @maxzongfen from student;
        select id into @idmax from student where zongfen=@maxzongfen;
        select name into @namemax from student where zongfen=@maxzongfen;
        insert into maxgrade(id,name,zongfen)value(@idmax,@namemax,@maxzongfen);
    end;
    insert student values(4,'d',177);

    之前

    之后

    触发器的特点:

    1.触发行为只能在之前或者之后执行(before,after)。

    2.触发器的命名可以重复(这里的重复是指两个不同的表可以起一个相同的触发器名字,但是每个表中的不同触发器的命名必须不同;但从程序的可读性等发面考虑还是应该在整个数据库中每个触发器的命名都应该不同,这种命名重复在我看来是MYSQL的弊端)。

    3.触发器可以产生增删改三种行为。

    4.触发器不能被覆盖或者修改,要更改触发器时需要先删除它,然后新建。

    删除语句drop TRIGGER 触发器名字;

    5.begin和end之间可以插入多条sql语句。

    6.触发器内不能调用存储过程。

    7.每张表最多可以建6个触发器,分别是增加、删除、添加行为前后。

    8.视图不支持触发器。

     备注一下:我得MYSQL版本为5.5.40。(查询语句为:select version();)

     转载本博客请在明显位置表明出处:http://www.cnblogs.com/liebagefly/p/7517998.html

    (谢谢配合,近期发现众多网站在引用本博客时不表明出处,故在此说明一下。)

  • 相关阅读:
    GZIPInputStream 流未关闭引起的内存泄漏问题
    Java ExcutorService优雅关闭方式
    redis pipline
    LeetCode 30与所有单词相关联的字串
    Scala不使用null 而使用Option,None,Some的好处
    记录: 一次解决整型溢出攻击(使用scala,隐式转换)
    Scala 封装可break和continue的foreach循环
    记录: 百度webuploader 分片文件上传java服务器端(spring mvc)示例的优化
    HBase shell 中的十六进制数值表示
    关于getSystemResource, getResource 的总结
  • 原文地址:https://www.cnblogs.com/liebagefly/p/7517998.html
Copyright © 2020-2023  润新知