zoukankan      html  css  js  c++  java
  • 触发器_02(trigger)简单实例

    1.已经介绍了触发器的定义以及适用场景,此时我们这里要实战一下:

    1.首先我们设计一个触发器的场景
        这里我们有两张表,一个goods表:里面对应的是商品的各种信息(gid,gname,gmuch)
        一个订单表order:里面是用户下的订单(oid,gid,omuch)
        设计原理:每当用户下订单后,商品表中的对应的商品数量会随着订单表的数量改变而变
    
    2. 建表
        create table goods(gid int not null,gname varchar(20),gmuch  int)engine=innodb;
    
        create table orders(oid int not null,gid int,omuch int ) engine=innodb;
    
    3.插入数据
        insert into goods values(1,'cat',100),(2,'dog',200),(3,'pig'300);

    2.创建触发器

    语法:
    create
    trigger 触发器名称 after/before(触发时间) insert /update/delete(监视事件) on 表名(监视地址) for each row begin sql1; .. sql2; end
    这里的逻辑是:当用户下订单时,买了几个商品后,goods的总商品数量就会减少几个,因此这里用的是关键字new,且用总商品数量-new.用户下的商品数量
    create
    trigger t1 after insert on orders for each row begin update goods set gmuch=gmuch-new.omuch where gid=new.gid; end $

    如果这里逻辑是:当用户取消订单时,这里是要用关键字old, 具体操作是用总商品的数量+old.用户取消的商品的数量

    delimiter $
    create trigger t2
    after
    delete
    on orders
    for each row
    begin
       update goods set gmuch=gmuch+old.omuch where gid=old.gid;
    end $


    #以上都是对数量进行插入和删除操作,如果可以对数量进行修改操作,那么该如何?
    delimiter $
    creater trigger t3
    before
    update
    on orders
    for each row
    begin
      update goods set gmuch=gmuch+old.omuch -new.omuch where gid=old.gid; ##这里的逻辑是先把旧行数据给返回去,然后再减掉新行的数据,这时就是此时商品中还剩的数量
    end $

     这里有几个问题?

      1.首先before与after到底有什么区别?

      2.如果用户购买的数量超过了商品库存总数,会发生什么情况?

    mysql> select * from goods;
    +-----+-------+-------+
    | gid | gname | gmuch |
    +-----+-------+-------+
    |   1 | cat   |    90 |
    |   2 | dog   |   299 |
    |   3 | pig   |   300 |
    +-----+-------+-------+
    3 rows in set (0.00 sec)
    
    mysql> select * from orders;
    +-----+------+-------+
    | oid | gid  | omuch |
    +-----+------+-------+
    | 121 |    1 |     2 |
    | 122 |    1 |     9 |
    +-----+------+-------+
    2 rows in set (0.00 sec)              ###这里我们可以发现cat的数量还剩90只,如果此时另外有个用户想买100只猫,此时会发生什么情况?
    
    mysql> insert into orders values(123,1,100);
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from goods;
    +-----+-------+-------+
    | gid | gname | gmuch |
    +-----+-------+-------+
    |   1 | cat   |   -10 |             ###这里看到商品库存中猫的数量变成了-10只,这样的情况在现实的数据库中是不允许的
    |   2 | dog   |   299 |
    |   3 | pig   |   300 |
    +-----+-------+-------+
    3 rows in set (0.00 sec)
    
    mysql> select * from orders;
    +-----+------+-------+
    | oid | gid  | omuch |
    +-----+------+-------+
    | 121 |    1 |     2 |
    | 122 |    1 |     9 |
    | 123 |    1 |   100 |
    +-----+------+-------+
    3 rows in set (0.00 sec)

    此时,我们可以再创建一个触发器进行如下操作

    delimiter $
    create  trigger t4
    before
    insert
    on orders
    for each row
    begin
        declare  rnum int;      ##声明变量
        select  gmuch  into rnum from goods where gid=new.gid;      ##into也是另一种赋值操作
        if new.omuch > rnum then
            set new.omuch = rnum;
        end if;
        update  goods set gmuch=gmuch - new.omuch where gid=new.gid;
    end $

    我们查看结果:

    mysql> select * from goods;
    +-----+-------+-------+
    | gid | gname | gmuch |
    +-----+-------+-------+
    |   1 | cat   |    90 |
    |   2 | dog   |   299 |
    |   3 | pig   |   300 |
    +-----+-------+-------+
    3 rows in set (0.00 sec)
    
    mysql> select * from orders;
    +-----+------+-------+
    | oid | gid  | omuch |
    +-----+------+-------+
    | 121 |    1 |     2 |
    | 122 |    1 |     9 |
    +-----+------+-------+
    2 rows in set (0.00 sec)
    
    mysql> insert into orders values(123,1,100);
    Query OK, 1 row affected (0.01 sec)
    
    mysql> select * from goods;
    +-----+-------+-------+
    | gid | gname | gmuch |
    +-----+-------+-------+
    |   1 | cat   |     0 |         ####此时这里的库存就是0,而不是负数了!
    |   2 | dog   |   299 |
    |   3 | pig   |   300 |
    +-----+-------+-------+
    3 rows in set (0.00 sec)
    
    mysql> select * from orders;
    +-----+------+-------+
    | oid | gid  | omuch |
    +-----+------+-------+
    | 121 |    1 |     2 |
    | 122 |    1 |     9 |
    | 123 |    1 |    90 |
    +-----+------+-------+
    3 rows in set (0.00 sec)

     补充:new和old的判断:

    如下图:

    触发器引用行变量

  • 相关阅读:
    lua 根据路径获取文件名
    python中的re模块
    正则表达式中的开头和结尾
    正则表达式匹配多个字符
    正则表达式中匹配单个字符
    正则表达式的作用
    gevent实现协程
    greenlet实现协程
    生成器的使用注意
    生成器实现斐波那契数列
  • 原文地址:https://www.cnblogs.com/zmc60/p/14643513.html
Copyright © 2011-2022 走看看