存储过程-进阶

2021-07-30  本文已影响0人  余于鱼不是鱼鱼鱼

通常,复杂的业务逻辑需要多条 SQL 语句。这些语句要分别地从客户机发送到服务器,当客户机和服务器之间的操作很多时,将产生大量的网络传输。如果将这些操作放在一个存储过程中,那么客户机和服务器之间的网络传输就会大大减少,降低了网络负载

1.存储过程的变量

1.定义变量

存储过程中,使用declare声明变量。通过两个简单的例子来说明存储过程中的变量

例1:使用set赋值

delimiter //
create procedure varTest()
begin
    # 声明变量employ_name
    declare employ_name varchar(32) default '';
    # 使用set语句给变量赋值
    set employ_name='你礼貌么';
    # 查看变量
    select employ_name;
end
//
delimiter ;

调用存储过程call varTest;,查看变量赋值结果

例2:使用select into赋值

有如下数据:

在存储过程中通过select into 把表中的数据赋值给声明的变量

delimiter //
create procedure varTest2()
begin
    # 声明变量employ_name
    declare employ_name varchar(32) default '';
    # 将employ表中id=52456456的名称赋值给employ_name
    select name into employ_name from employ where id=52456456;
    # 查看变量
    select employ_name;
end
//
delimiter ;

调用存储过程call varTest2;,查看变量赋值结果

2.变量的作用域

在存储过程中,变量也存在作用域,作用域范围在变量申明的begin-end代码块中

delimiter //
create procedure varScopeTest()
begin
    begin
        # 第一个begin-end
        declare employ_name varchar(32) default '';
        # 将employ表中id=52456456的名称赋值给employ_name
        select name into employ_name from employ where id=52456456;
        # 查看变量
        select employ_name;
    end;
    begin
        # 第二个begin-end
        # 调用第一个begin-end中的employ_name 变量
        select employ_name;
    end;
end
//
delimiter ;

调用存储过程call varScopeTest

这里由于employ_name变量作用域只在第一个begin-end,在第二个begin-end中使用的时候就会报Unknown错误

如果需要在多个同级begin-end中使用同一个变量,则需要在上一级begin-end中声明

delimiter //
create procedure varScopeTest3()
begin
    declare employ_name varchar(32) default '你礼貌么';
    begin
        # 将employ表中id=52456456的名称赋值给employ_name
        select name into employ_name from employ where id=52456456;
        # 查看变量
        select employ_name;
        # 使用set改变变量的值
        set employ_name='你礼貌么';
    end;
    begin
        select employ_name;
    end;
end
//
delimiter ;

调用存储过程,查看结果

通过结果可以看到,变量定义为成员变量后。在其后的begin-end块共享这个变量

2.存储过程的条件判断分支

任何一门编程语言都少不了条件判断,存储过程同样有,他的语法格式如下:

if(条件1) then 分支代码块1....
elseif(条件2) then 分支代码块2...
elseif(条件n) then 分支代码块n...
else 所有条件都不满足时进入该代码块...
end if;

编写存储过程判断奇数偶数

delimiter //
create procedure assertTest(in num integer)
begin
    declare message varchar(100) default '';
    if(num & 1 = 0) then set message='传入的是偶数';
    else set message='传入的是奇数';
    end if;
    select message;
end
//
delimiter ;

注意:在存储过程中是否相等用=(一个等于号)

调用存储过程查看结果

3.存储过程的循环

在mysql存储过程的语句中有三个标准的循环方式:

WHILE 循环条件(为true则执行,否则无法执行) DO
          循环体
END WHILE

使用存储过程实现拼接0-9

delimiter //
create procedure whileTest()
begin
    declare idx integer default 0;
    declare message varchar(100) CHARACTER SET utf8 default '';

    while idx < 10 do
           set message=concat(message,idx,',');
           set idx=idx+1;
    end while;

    select message;
end
//
delimiter ;

执行结果如下

while循环总是在执行前检查语句的表达式,对比java中while循环

loop_name:LOOP
    IF 条件表达式 THEN -- 满足条件时离开循环
        LEAVE loop_name;  -- 和 break 差不多都是结束训话
    END IF;
END LOOP;
delimiter //
create procedure loopTest()
begin
    declare idx integer default 0;
    declare message varchar(100) CHARACTER SET utf8 default '';

    concat_loop:LOOP
        IF idx>10 THEN -- 满足条件时离开循环
            LEAVE concat_loop;  -- 和 break 差不多都是结束训话
        END IF;
        set message=concat(message,idx,',');
        set idx=idx+1;
    END LOOP;

    select message;
end
//
delimiter ;

调用存存储过程结果如下

loop循环要明确退出条件,不然会导致死循环。leave 的作用就是结束循环,相当于java中的break

REPEAT
          循环体
UNTIL 循环条件(为false则执行,否则无法执行)
END REPEAT
delimiter //
create procedure repeatTest()
begin
    declare idx integer default 0;
    declare message varchar(100) CHARACTER SET utf8 default '';

    repeat
            set message=concat(message,idx,',');
            set idx=idx+1;
        until idx>10
    end repeat;

    select message;
end
//
delimiter ;

调用存储过程

repeat循环先执行一次再检查循环条件,所以无论如何repeat循环都至少执行一次,对比java中do...while

上一篇 下一篇

猜你喜欢

热点阅读