MySQL之存储过程(循环)

liandaozhanshi / 2023-07-23 / 原文

MySQL之存储过程

变量

@@是系统变量

@是用户自定义的变量

系统变量

系统变量 是MySQL服务器提供,不是用户定义的,属于服务器层面。分为全局变量(GLOBAL)、会话变量(SESSION)。

查看系统变量

模板

 SHOW [ SESSION | GLOBAL] VARIABLES ;             -- 查看所有系统变量
 SHOW [SESSION|GLOBAL] VARIABLES LIKE '........'; -- 可以通过LIKE模糊匹配方式查找变量
 SELECT @@[SESSION | GLOBAL] 系统变量名;           -- 查看指定变量的值

实操

 show session variables ;
 ​
 show session variables like 'auto%';
 show global  variables like 'auto%';
 ​
 select @@autocommit;
 select @@global.autocommit;
 ​
 -- 设置系统变量
 set session autocommit = 0;


注意:

  1. 如果没有指定SESSION/GLOBAL,默认是SESSION,会话变量。

  2. mysql服务重新启动之后,所设置的全局参数会失效,要想不失效,可以在 /etc/my.cnf 中配置。


用户定义的变量

用户定义变量 是用户根据需要自己定义的变量,用户变量不用提前声明,在用的时候直接用“@变量名”使用就可以。其作用域为当前连接(当前会话)

注意: 用户定义的变量无需对其进行声明或初始化,只不过获取到的值为NULL。

赋值

赋值建议使用 := ,因为MySQL中没有 == , = 既可以做赋值运算符,又可以做比较运算符,所以赋值建议使用 :=

 SET @var name = expr [, @var_name = expr] ... ;
 SET @var_name := expr [, @var_name := expr] ... ;
 SELECT @var name := expr [, @var_name := expr] ... ;
 SELECT 字段名 INTO @var_name FROM 表名;

使用

 SELECT @var_name ;

实操

 -- 变量:用户变量
 -- 赋值
 set @myname := 'itheng';
 set @myage := 20;
 set @mygender := '男',@myhobby := 'Java';
 ​
 -- 使用
 select @myname,@myage,@mygender,@myhobby;
 ​
 select count(*) into @mycount from tb_user;
 select @mycount;
 ​
 select @myname; #用户定义的变量无需对其进行声明或初始化,只不过获取到的值为NULL。

局部变量

局部变量 是根据需要定义的在局部生效的变量,访问之前,需要DECLARE声明。可用作存储过程内的局部变量和输入参数,局部变量的范围是在其内声明的BEGIN ...END块。

声明

 DECLARE 变量名 变量类型[DEFAULT ...];

变量类型就是数据库字段类型:INT、BIGINT、CHAR、VARCHAR、DATE、TIME等。

赋值

 set 变量名 = 值;
 set 变量名 := 值;
 SELECT 字段名 INTO 变量名 FROM 表名...;
 -- 变量:局部变量
 -- 声明:declare
 -- 赋值
 create procedure p2()
 begin
     declare stu_count int default 0;
     select count(*) into stu_count from student;
     select stu_count;
 end;
 ​
 call p2();

存储过程语法(基于局部变量)

if

语法:

 if 条件1 then
     ...
 elseif 条件2 then     --可选
     ...
 else                --可选
     ...
 end if;

实操:

 create procedure p1()
 begin
     declare score int default 59;
     declare degree char(10) ;
     if score < 60 then
         set degree := '不及格';
     elseif score >=60 and score <85 then   #注意:elseif如果分开写,则会报错
         set degree :='及格';
     else
         set degree :='优秀';
     end if;
     select degree;
 end;
 ​
 call p1();

参数

类型 含义
IN 该类参数作为输入,也就是需要调用时传入值
OUT 该类参数作为输出,也就是该参数可以作为返回值
INOUT 既可以作为输入参数,也可以作为输出参数

用法:

 create procedure 存储过程名称([IN/OUT/INOUT参数名 参数类型])
 begin
     --SQL语句
 end;

实操:

 #给分数分等级
 create procedure p2(in score int , out degree varchar(10))
 begin
     if score < 60 then
         set degree := '不及格';
     elseif score >=60 and score <85 then   #注意:elseif如果分开写,则会报错
         set degree :='及格';
     else
         set degree :='优秀';
     end if;
     select degree;
 end;
 ​
 call p2(58,@degree);
 #将传入的200分制的分数,换算成百分制。
 create procedure p3(inout score double)
 begin
     set score = 0.5 * score;
     select @score;
 end;
 ​
 set @score = 78 ;
 call p3(@score); 
 -- 不能在p3括号里对@score进行赋值,存储过程的参数需要在 CALL 语句中指定,并且不能使用赋值操作符。

case

语法1:

 case case_balue
     when when_value1 then statement_list1
     [when when_value2 then statement_list2]...
     [else statement_list]
 end case;

语法2:

 case
     when search_condition then statement_list1
     [when search condition2 then statement_list2]....
     [else statement_list]
 end case;

实操:

 DELIMITER //
 ​
 CREATE PROCEDURE p6(IN month INT)
 BEGIN
     DECLARE result VARCHAR(10);
     CASE
         WHEN month >= 1 AND month <= 3 THEN
             SET result := '第一季度';
         WHEN month >= 4 AND month <= 6 THEN
             SET result := '第二季度';
         WHEN month >= 7 AND month <= 9 THEN
             SET result := '第三季度';
         WHEN month >= 10 AND month <= 12 THEN
             SET result := '第四季度';
         ELSE
             SET result := '非法参数';
         END CASE;
 ​
     SELECT CONCAT('您输入的月份为:', month, ',这所属的季度为:', result);
 END //
 ​
 DELIMITER ;
 call p6(5);

while

语法

while循环是有条件的循环控制语句。满足条件后,再执行循环体中的SQL语句。具体语法为:

 #先判定条件,如果条件为true,则执行逻辑,否则,不执行逻辑。
 while 条件 do
     sql逻辑...
 end while;

实操

 create procedure p7(in n int)
 begin
     declare total int default 0;
     while n > 0 do
         set total := total + n;
         set n := n - 1;
     end while;
     select total;
 end;
 ​
 call p7(10);

repeat

语法

repeat是有条件的循环控制语句,当满足条件的时候退出循环,具体语法为:

 #先执行一次逻辑,然后判定逻辑是否满足,如果满足,则退出。如果不满足,则继续下一次循环。
 repeat
     sql逻辑...
     until 条件
 end repeat;

实操

 create procedure p8(in n int)
 begin
     declare total int default 0;
 ​
     repeat
         set total := total + n;
         set n := n - 1;
     until n <= 0
     end repeat;
 ​
 select total;
 end;
 ​
 call p8(10);