zoukankan      html  css  js  c++  java
  • MySQL存储过程02

    这次接着说MySQL存储过程:

    我们先看它的多分支控制结构case:

    case的语句很简单: 

    case 变量名

    when 条件1 then 输出结果1;

    when 条件2 then 输出结果2;

    ......

    end case;

    那我们就来建立一个存储过程实现它:

    create procedure p10()
    begin
    declare pos int default 0;
    set pos:= floor(5*rand());
    case pos
    when 1  then select'我会飞';
    when 2 then select'我掉到海里';
    when 3 then select'我在小岛';
    else select'我不知道我在哪';
    end case;
    end$

    由于我们设置的是随机数,所以它会根据我们生成的数来输出结果

    接着看一下repeat循环:

    repeat的语法:

    repeat

    sql statement;

    sql statement;

    ...

    until condition end repeat;

    create procedure p11()
    begin
    declare total int default 0;
    declare i int default 0;
    repeat
    set i:=i+1;
    set total:=total+i;
    until i>=100 
    end repeat;
    select total;
    end$

    游标:

    一条sql,对应N条资源,取出资源的接口/句柄,就是游标

    沿着游标,可以一次取出一行。

    建立游标的语法:

    declare 游标名 cursor for sql语句;

    open 游标名

    fetch 游标名 into 变量1,变量2,...变量N;

    close 游标名

    create procedure p12()
    begin
    declare row_gid int;
    declare row_name varchar(20);
    declare row_num int;
    declare getgoods cursor for select gid,num,name from goods;
    open getgoods;
    fetch getgoods into row_gid,row_num,row_name;
    select row_num,row_name;
    close getgoods;
    end$

     

    那么我们看到这个输出结果没有什么特别的地方,那么如果我们把游标改一改?

    create procedure p13()
    begin
    declare row_gid int;
    declare row_name varchar(20);
    declare row_num int;
    declare getgoods cursor for select gid,num,name from goods;
    open getgoods;
    fetch getgoods into row_gid,row_num,row_name;
    select row_num,row_name;
    fetch getgoods into row_gid,row_num,row_name;
    select row_num,row_name;
    fetch getgoods into row_gid,row_num,row_name;
    select row_num,row_name;
    fetch getgoods into row_gid,row_num,row_name;
    select row_num,row_name;
    close getgoods;
    end$

    我们看到在输出了三行之后报错,那么我们可以把循环和游标结合起来:

    create procedure p14()
    begin
    declare row_gid int;
    declare row_name varchar(20);
    declare row_num int;
    declare cnt int default 0; #声明一个变量用来计数
    declare i int default 0;
    declare getgoods cursor for select gid,num,name from goods;
    select count(*) into cnt from goods; #将总行数赋给cnt
    open getgoods;
    repeat
    set i:=i+1;
    fetch getgoods into row_gid,row_num,row_name;
    select row_num,row_name;
    until i>=cnt end repeat;
    close getgoods;
    end$

    其实游标在越界时我们可以用declare continue handler 来操作一个越界标志

    declare continue handler for NOT FOUND 可执行语句;

    create procedure p15()
    begin
    declare row_gid int;
    declare row_name varchar(20);
    declare row_num int;
    declare you int default 1;
    declare getgoods cursor for select gid,num,name from goods;
    declare continue handler for NOT FOUND set you:=0;
    open getgoods;
    repeat
    fetch getgoods into row_gid,row_num,row_name;
    select row_num,row_name;
    until you=0 end repeat;
    close getgoods;
    end$

    在上面的结果中我们发现最后一行被取了两次,这是为什么?

    答:因为我们声明的是continue型handler,那么它在把you 这个变量改为0后还会接着执行后面的sql语句,我们把continue改为exit就不会出现这种情况了:

    create procedure p15()
    begin
    declare row_gid int default 0;
    declare row_num int default 0;
    declare row_name varchar(20);
    declare you int default 1;
    declare getgoods cursor for select gid,num,name from goods;
    declare exit handler for NOT FOUND set you:=0;
    open getgoods;
    repeat
    fetch getgoods into row_gid,row_num,row_name;
    select row_name,row_num;
    until you=0 end repeat;
    close getgoods;
    end$

    那么其实我们还有另一种方法来修改:我们使逻辑上更加通顺

    create procedure p17()
    begin
    declare row_gid int;
    declare row_num int;
    declare row_name varchar(20);
    declare you int default 1;
    declare getgoods cursor for select gid,num,name from goods;
    declare continue handler for NOT FOUND set you:=0;
    open getgoods;
    fetch getgoods into row_gid,row_num,row_name;
    repeat
    select row_name,row_num;
    fetch getgoods into row_gid,row_num,row_name;
    until you=0 end repeat;
    close getgoods;
    end$

    或者是将repeat改为while循环,在这里我就不列举了。

  • 相关阅读:
    【原】iOS学习之XML与JSON两种数据结构比较和各自底层实现
    ios 10 访问设置问题
    蛇形输出
    苹果内购流程详解
    iOS多线程比较
    App iCON 尺寸
    学习网站
    c++ lesson 一(命名空间输入输出)
    iOS中WebSocket的使用
    MAC TXT文本
  • 原文地址:https://www.cnblogs.com/wanghaoyu666/p/11322221.html
Copyright © 2011-2022 走看看