• Mysql -- 触发器


    触发器定义

      触发器是一类特殊的事务,可以监视某种数据操作(insert、update、delete),并触发相关操作。

      触发器简单一点解释就是,当一张表中的数据发生改变时,关联的另外一张表中的数据也会发生改变。触发事件的操作和触发器里的SQL语句是一个事务操作,具有原子性,要么全部执行,要么都不执行,可以保证数据的完整性。

    应用场合

      1、当一个订单产生时,订单所购的商品的库存量相应减少。

      2、当某客户进行欠款消费,可以再生成订单时通过设计触发器判断该客户的累计欠款是否超出了最大限度。

      3、当有新订单产生时,需要及时通知相关人员进行处理,此时可以在订单表上设计添加触发器加以实现。

    创建语法4要素

      1、监视地点:table

      2、监视事件:insert、update、delete

      3、触发时间:after、before

      4、触发事件:insert、update、delete

     创建一个触发器

      1.创建两张表,一张是商品库存表,一张是订单表,sql如下:  

    create table goods (

    gid int,

    name varchar(20),

    num smallint

    );

    create table ord (

    oid int,

    gid int,

    much smallint

    );

    insert into goods values

    (1,'cat',34),

    (2,'dog',65),

    (3,'pig',21);

    2.创建一个简单触发器

    create trigger t1
    after
    insert
    on ord
    for each row
    begin
    update goods set num=num-new.much where gid=new.gid;
    end;

    通过show triggers查看

      3.测试一下

    select * from goods;
    insert into ord values(100,1,2);
    select * from ord;
    select * from goods;

      4.模仿insert创建一个delete触发器

    create trigger t2
    after
    delete
    on ord
    for each row
    begin
    update goods set num=num+old.much where gid=old.gid;
    end;

      5.新增和删除已经做完了,修改订单呢?

    create trigger t3
    before
    update
    on ord
    for each row
    begin
    update goods set num=num+old.much-new.much where gid=old.gid;
    end;

      测试下:

    select * from goods;
    select * from ord;
    update ord set much=3 where oid=100;
    select * from ord;
     

    6.after和before的区别

    目前为止after和before似乎并没有任何不同。想一下,如果库存只有3只猫了,但客户买了5只,会发生什么?

    库存中猫的数量变成-2只,这就是传说中的爆仓。怎么办?如何预防这种情况发生?

    可以再购买量much>库存量num时,把much自动改为num。

    create trigger t5
    after
    insert
    on ord

    for each row
    begin
    declare
    rnum int;

    select num into rnum from goods where gid=new.gid;
    if new.much > rnum then
    set new.much = rnum;
    end if;

    update goods set num=num-new.much where gid=new.gid;
    end;

    创建时报错如下:

    [Err] 1362 - Updating of NEW row is not allowed in after trigger

       after trigger为数据已经插入磁盘之后触发,上面的触发器在数据插入数据库之后再set,已经没有意义了。因此需要改为before

    create trigger t5
    before
    insert
    on ord

    for each row
    begin
    declare
    rnum int;

    select num into rnum from goods where gid=new.gid;
    if new.much > rnum then
    set new.much = rnum;
    end if;

    update goods set num=num-new.much where gid=new.gid;
    end;

    测试如下:

    select * from goods;
    insert into ord values(100,3,23);
    select * from ord;
    select * from goods;

  • 相关阅读:
    初学java
    位操作运算符的最好的解释
    C++手机通讯录排序
    删除TFS项目上的文件
    单元测试中方法运行测试和调试测试不起作用原因
    EF-CodeFirst系列100
    NPOI-Excel系列-1002.创建带有Document Summary Information和Summary Information的Excel文件
    NPOI-Excel系列-1000.创建一个标准的Excel文件
    T4模板批量生成代码文件
    WebService返回json格式数据供苹果或者安卓程序调用
  • 原文地址:https://www.cnblogs.com/bwyhhx2018/p/10704320.html
Copyright © 2020-2023  润新知