zoukankan      html  css  js  c++  java
  • 数据库触发器

    触发器 trigger
    	创建create trigger t1
    	删除drop trigger t1
    	查看show triggers G
    需求
    商品表goods
    订单表prd
    
    当下一个订单 对应商品相对减少(买几个少几个
    
    分析
    监视谁 prd
    监视动作 insert
    触发时间 after
    触发事件 update
    
    create trigger t1
    after
    insert
    on prd
    for each row
    begin
    update goods xxxxx
    end;
    
    创建表
    create table goods(
    	gid int,
    	name varchar(20),
    	num smallint
    );
    
    create table prd(
    	pid int,
    	gid int,
    	much smallint
    );
    
    创建数据
    insert into goods values
    (1,'cat',34),
    (2,'dog',65),
    (3,'pig',21);
    
    insert into prd values(1,1,2);
    
    创建触发器(	加$符号使数据库识别该语句为不分行)
    delimiter $
    create trigger t1
    after
    insert
    on prd
    for each row
    begin
    update goods set num=num-2 where gid=1;
    end$
    问题:为什么买什么都减少两只猫呢
    答案:因为触发器减少的gid=1,这里要动态引入变量
    
    (增加)触发器引入变量new
    delimiter $
    create trigger t2
    after
    insert
    on prd
    for each row
    begin
    update goods set num=num-new.much where gid=new.gid;
    end$
    
    (删除)触发器引入变量old
    delimiter $
    create trigger t3
    after
    delete
    on prd
    for each row
    begin
    update goods set num=num+old.much where gid=old.gid;
    end$
    
    (更改)触发器引入变量old
    delimiter $
    create trigger t4
    before
    update
    on prd
    for each row
    begin
    update goods set num=num+old.much-new.much where gid=new.gid;
    end$
    
    思考:before和after的区别
    	  如果剩余3头猪,但客户下单买10头,会发生什么情况?(会爆仓 库存变为负数)怎么防止?
    	  能否在购买量much>库存量num时,把much自动改为num(使用before)
    
    在t2基础上完成much和num的判断
    create trigger t5
    after
    insert
    on prd
    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$	
    这样会报错:
    Updating of NEW row is not allowed in after trigger
    原因:insert之后,new行已经插入到表中,已经成为事实,改new已经来不及了
    
    在t5基础上,继续改进
    create trigger t6
    before
    insert
    on prd
    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$
    
    在触发器中 for each row是干嘛的
    在Oracle触发器中,触发器分语句级触发器,和行级触发器(每一行受影响,触发器都执行)
    比如
    create trigger th
    after update
    on xxtable
    for each row
    begin 
    	sqlN
    end$
    当执行:update xxtable set xxx=xxx where id>100;
    那么sqlN会被触发100次
    
    在Oracle中for each row如果不写
    无论update语句执行多少行,都执行一次
    

      

  • 相关阅读:
    数以百万计美元的融资YO是什么东东?
    工作流和审批流
    Linux makefile 教程 很具体,且易懂
    【吐槽】火车票一票难求啊
    poj 2828 Buy Tickets(树状数组 | 线段树)
    如花搞笑图片集锦(转贴)
    苹果开发人员账号注冊流程
    优秀团队建设--美国式团队(ppt)
    屏幕分辨率(QQVGA、QVGA、VGA、XGA、WXGA、WUXGA和WSXGA+)
    怎样设计接口?
  • 原文地址:https://www.cnblogs.com/aten/p/9380526.html
Copyright © 2011-2022 走看看