zoukankan      html  css  js  c++  java
  • MySQL学习(十六)

    MySQL高级部分
    触发器
    触发器是一类特殊的事务,可以监视某种数据操作(insert/update/delete),并触发相关的操作(insert/update/delete)
    触发器创建语法之4要素
    1 监视地点table
    2 监视事件insert/update/delete
    3 触发时间after/before
    4 触发事件

    查看已有的触发器

    show triggers
    

    删除已有的触发器

    drop trigger triggerName
    

    创建一个触发器

    create trigger t1
    after
    insert on ord
    for each row
    begin
    update goods1 set num = num - 2 where gid = 1;
    end$
    

    上面语句中,如果insert(被监视的语句),产生的数据,能否在触发器中引用到?

    更改之后的触发器,引入了参数

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

    删除订单的触发器

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

    改订单数量

    create trigger t4
    before
    update 
    on ord
    for each row
    begin
    update goods1 set num = num + (old.much - new.much) where gid = old.gid;
    end$
    

    思考:before目前似乎没有看出与after的区别?
    再思考:如果剩余的库存量只有3个,但客户要买10个,就会出现问题
    一个问题

    能否在购买量 much > 库存量num时,把much自动改为num
    提示:before的作用
    在t2的基础上,完成much与num的判断

    create trigger t5
    after
    insert on ord
    for each row
    begin
    declare 
    rnum int;
    select num into rnum from goods1 where gid = new.gid;
    if new.much > rnum then
        set new.much = rnum;
    end if
    update goods1 set num = num -new.much where gid = new.gid;
    end$
    

    提示错误

    ERROR 1362 (HY000): Updating of NEW row is not allowed in after trigger
    

    原因:insert之后,new行已经插入到表中,成为事实,改new已经晚了
    修改
    在t2的基础上,完成much与num的判断

    create trigger t5
    before
    insert on ord
    for each row
    begin
    declare 
    rnum int;
    select num into rnum from goods1 where gid = new.gid;
    if new.much > rnum then
        set new.much = rnum;
    end if;
    update goods1 set num = num -new.much where gid = new.gid;
    end$
    

    insert 只能引用新行 new
    delete 只能引用旧行 old
    update可以引用新行和旧行,新行为new,旧行为old

    触发器for each row是干吗的?
    在oracle的触发器中,触发器可以分为语句级触发器和行级触发器
    执行
    update xxtable set xxx=xxx where id > 100; #修改了100行
    那么sqlN会被触发几次?
    100次

    create trigger t5
    before
    insert on ord
    for each row #每一行受影响,触发器都执行,叫做行级触发器
    begin
    declare 
    rnum int;
    select num into rnum from goods1 where gid = new.gid;
    if new.much > rnum then
        set new.much = rnum;
    end if;
    update goods1 set num = num -new.much where gid = new.gid;
    end$
    在orcal中
    for each row如果不写,无论update语句一次影响了多少行,都只执行一次。
    比如:1人下了订单,买了5件商品,insert 5 次,可以用行级触发器,修改5次库存,
    用语句级触发,insert一条发货提醒。
    遗憾的是,MySQL目前不支持语句级触发器。
    for each row 声明行级触发器
    

    存储过程和函数
    创建存储过程的语法
    create procedure procedureName()
    begin
    --sql语句
    end$
    调用存储过程
    call procedure();
    删除存储过程

    drop procedure procedureName
    

    创建存储过程语法

    create procedure p1()
    begin 
        select 'hello' from dual;
    end$
    

    存储过程是可以编程的,意味着可以使用变量,表达式,控制结构来完成复杂的功能
    在存储过程中,用declare声明变量
    格式 declare 变量名 变量类型 [default 默认值]
    引入变量

    create procedure p2()
    begin
        declare age int default 18;
    	declare height int default 180;
    	select concat('年龄是',age,'身高是',height);
    end$
    

    存储过程中,变量可以做sql语句中合法的运算,如加减乘除,
    注意,运算的结果,如何赋值给变量
    set 变量名 := expression

    create procedure p3()
    begin
        declare age int default 18;
    	declare height int default 180;
    	set age := age + 20;
    	select concat('年龄是',age,'身高是',height);
    end$
    

    if/else控制结构

    if condition then 
      statement
    else
    end;
    

    存储过程的括号里可以声明参数
    语法是 [in/out/inout] 参数名 参数类型
    给存储过程传递参数

    create procedure p6(width int,height int)
    begin
    	declare area int default 0;
        if width > height then
    	    select '这个矩形比较宽';
        elseif width < height then
    	    select '这个矩形比较高';
    	else
    		select '这个矩形是个方的';
        end if;
    	set area := width * height;
        select area;
    end$
    

    控制结构有三大类,顺序,选择,循环。
    while的语法

    WHILE expr_condition DO
        statement_list
    END WHILE
    
    create procedure p7()
    begin
        declare total int default 0;
    	declare num int default 0;
    	while num < 101 do
    	    set total := total + num;
    		set num := num + 1;
    	end while;
    	select total;
    end$
    

    in类型的参数,in代表input

    create procedure p8(in n int)
    begin
        declare total int default 0;
    	declare num int default 0;
    	while num < n do
    		set num := num + 1;
    	    set total := total + num;
    	end while;
    	select total;
    end$
    

    out型

    create procedure p9(in n int,out total int)
    begin
    	declare num int default 0;
    	set total := 0;
    	while num < n do
    		set num := num + 1;
    	    set total := total + num;
    	end while;
    end$
    

    调用

    call p9(100,@sum)$
    select @sum$
    

    inout类型
    CASE,LOOP,IF,LEAVE,ITERATE,REPEAT,WHILE语句

  • 相关阅读:
    NTKO Officecontrol在线Word编辑器的使用
    SQL数据类型解释
    经典SQL语句大全(网络资源共享)
    Ext.grid.GridPanel属性及方法等
    C#简易播放器(基于开源VLC)
    委托,是我委托你处理事件
    .NET面试必备(整理)
    SQL server 数据库连接方式分析
    FTP操作类的使用
    微信企业号平台开发之获取菜单,创建菜单和删除菜单
  • 原文地址:https://www.cnblogs.com/Manual-Linux/p/10217220.html
Copyright © 2011-2022 走看看