MySQL的控制结构

MySQL的控制结构

在MySQL数据库中定义存储过程、触发器时,可能会用到条件判断、循环等控制结构,现总结如下:

一、数据准备

创建stu(学生)表,代码如下:

create table employee(
    e_id int auto_increment,
    e_name char(20),
    sex char(2),
    salary int,
    phone char(20),
    addr varchar(100),
    constraint pk_employee_eid primary key(e_id)
);

为stu表输入数据,代码如下:

insert into employee(e_id,e_name,sex,salary,phone,addr)
values(1001,'张平','女',15000,'13703735566','河南省新乡市'),(1002,'王刚','男',8500,'13703714422','河南省郑州市'),
(1003,'张静静','女',5900,'13803716666','河南省郑州市'),(1004,'王涛','男',21000,'13703732211','河南省新乡市'),
(1005,'王鹏飞','男',15600,'13723750122','河南省安阳市'),(1006,'王强军','男',8900,'13736890126','河南省安阳市'),
(1007,'刘晶晶','女',5200,'13782576666','河南省安阳市'),(1008,'张梅梅','女',6500,'13688884412','河南省开封市');

二、条件判断

MySQL数据库中的判断结构有两种,IF结构和CASE结构。

1、IF判断结构

if 条件表达式1 then 
   命令序列1
   [elseif 条件表达式2 then 
      命令序列2]  
   [elseif 条件表达式3 then 
      命令序列3]  
   ...
   [elseif 条件表达式n then 
      命令序列n]  
   [else 
      命令序列n+1]  
end if;  

例子:创建一个存储过程sp_emp_1,判断每一名员工的工资等级。代码如下:

delimiter //
create procedure sp_emp_1()
begin
	declare emp_name char(20) default '';
	declare emp_salary int default 0;
	declare flag int default 1;
	declare salary_grade char(20) default 0;
	declare cur_emp cursor for select e_name,salary 
            from employee where addr='河南省安阳市';
	declare continue handler for not found set flag:=0;
	
	open cur_emp;
	fetch cur_emp into emp_name,emp_salary;
	
	while flag=1 do
       if (emp_salary>=5000 and emp_salary<8000) then
            set salary_grade:='一级工资';
       elseif (emp_salary>=8000 and emp_salary<10000) then
            set salary_grade:='二级工资';
       elseif (emp_salary>=10000 and emp_salary<12000) then
            set salary_grade:='三级工资';
       elseif (emp_salary>=12000) then
            set salary_grade:='四级工资';
       else
            set salary_grade:='试用期工资';
       end if;
       select emp_name,emp_salary,salary_grade;

       fetch cur_emp into emp_name,emp_salary;
    end while;
end //
delimiter ;

调用存储过程,运行结果如下:

mysql> call sp_emp_1();
+-----------+------------+--------------+
| emp_name  | emp_salary | salary_grade |
+-----------+------------+--------------+
| 王鹏飞    |      15600 | 四级工资     |
+-----------+------------+--------------+
1 row in set (0.00 sec)

+-----------+------------+--------------+
| emp_name  | emp_salary | salary_grade |
+-----------+------------+--------------+
| 王强军    |       8900 | 二级工资     |
+-----------+------------+--------------+
1 row in set (0.00 sec)

+-----------+------------+--------------+
| emp_name  | emp_salary | salary_grade |
+-----------+------------+--------------+
| 刘晶晶    |       5200 | 一级工资     |
+-----------+------------+--------------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

2、CASE结构

CASE结构有两种用法:

(1)格式一

比较when后面的表达式和case后面的表达式,如果相等则执行该when后面的命令序列。

case 表达式
	when 表达式1 then
		命令序列1;
	when 表达式2 then
		命令序列2;
	....
	when 表达式n then
		命令序列n;
    else
        命令序列n;
end CASE;

例子:

delimiter //
create procedure sp_emp_2()
begin
	declare emp_addr varchar(100);
	declare emp_cun_xinxiang int default 0;
	declare emp_cun_anyang int default 0;
	declare emp_cun_zhengzhou int default 0;
	declare emp_cun_kaifeng int default 0;
	
	declare flag int default 1;
	
	declare cur_emp cursor for select addr from employee;
	
	declare continue handler for not found set flag:=0;
	
	open cur_emp;
	fetch cur_emp into emp_addr;
	
	while flag=1 do
       case emp_addr
       when '河南省新乡市' then
            set emp_cun_xinxiang:=emp_cun_xinxiang+1;
       when '河南省郑州市' then
            set emp_cun_zhengzhou:=emp_cun_zhengzhou+1;
       when '河南省安阳市' then
            set emp_cun_anyang:=emp_cun_anyang+1;
       when '河南省开封市' then
            set emp_cun_kaifeng:=emp_cun_kaifeng+1;
       end case;
       
       fetch cur_emp into emp_addr;
    end while;
    select '各地市人数:',emp_cun_xinxiang,emp_cun_zhengzhou,emp_cun_anyang,emp_cun_kaifeng;
end //
delimiter ;

运行存储过程,查询结果如下:

mysql> call sp_emp_2();
+--------------------+------------------+-------------------+----------------+-----------------+
| 各地市人数:       | emp_cun_xinxiang | emp_cun_zhengzhou | emp_cun_anyang | emp_cun_kaifeng |
+--------------------+------------------+-------------------+----------------+-----------------+
| 各地市人数:       |                2 |                 2 |              3 |               1 |
+--------------------+------------------+-------------------+----------------+-----------------+
1 row in set (0.01 sec)

(2)格式二

case后面空白,when后面直接加入判断条件,如果某个when后面的条件表达式成立,则执行其后面的命令序列。

case 
	when 条件表达式1 then
		命令序列1;
	when 条件表达式2 then
		命令序列2;
	....
	when 条件表达式n then
		命令序列n;
    else
        命令序列n+1;
end CASE;

例如:把存储过程sp_emp_1中的IF判断替换成CASE,代码如下:

delimiter //
create procedure sp_emp_3()
begin
	declare emp_name char(20) default '';
	declare emp_salary int default 0;
	declare flag int default 1;
	declare salary_grade char(20) default 0;
	declare cur_emp cursor for select e_name,salary 
            from employee where sex='男';
	declare continue handler for not found set flag:=0;
	
	open cur_emp;
	fetch cur_emp into emp_name,emp_salary;
	
	while flag=1 do
       case
       when (emp_salary>=5000 and emp_salary<8000) then
            set salary_grade:='一级工资';
       when (emp_salary>=8000 and emp_salary<10000) then
            set salary_grade:='二级工资';
       when (emp_salary>=10000 and emp_salary<12000) then
            set salary_grade:='三级工资';
       when (emp_salary>=12000) then
            set salary_grade:='四级工资';
       else
            set salary_grade:='试用期工资';
       end case;
       select emp_name,emp_salary,salary_grade;

       fetch cur_emp into emp_name,emp_salary;
    end while;
end //
delimiter ;

运行存储过程,查询结果如下:

mysql> call sp_emp_3();
+----------+------------+--------------+
| emp_name | emp_salary | salary_grade |
+----------+------------+--------------+
| 王刚     |       8500 | 二级工资     |
+----------+------------+--------------+
1 row in set (0.00 sec)

+----------+------------+--------------+
| emp_name | emp_salary | salary_grade |
+----------+------------+--------------+
| 王涛     |      21000 | 四级工资     |
+----------+------------+--------------+
1 row in set (0.00 sec)

+-----------+------------+--------------+
| emp_name  | emp_salary | salary_grade |
+-----------+------------+--------------+
| 王鹏飞    |      15600 | 四级工资     |
+-----------+------------+--------------+
1 row in set (0.00 sec)

+-----------+------------+--------------+
| emp_name  | emp_salary | salary_grade |
+-----------+------------+--------------+
| 王强军    |       8900 | 二级工资     |
+-----------+------------+--------------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

三、循环结构

1、while循环

while循环的语法如下:

while 循环条件 do  
   语句序列;
end while;

例子:定义一个函数func_sum,求1到n之间所有自然数的和。

delimiter //
create function func_sum(n int) 
returns int no sql
begin
    declare sumA int default 0;
    declare i int default 1;
    if n<=0 then
        return 0;
    else
        while (i<=n) do
            set sumA:=sumA+i;
            set i:=i+1;
        end while;
        return sumA;
    end if;
end //
delimiter ;

调用函数func_sum,结果如下:

mysql> select func_sum(100);
+---------------+
| func_sum(100) |
+---------------+
|          5050 |
+---------------+
1 row in set (0.00 sec)

mysql> select func_sum(-100);
+----------------+
| func_sum(-100) |
+----------------+
|              0 |
+----------------+
1 row in set (0.00 sec)

2、repeat循环

repeat循环的语法如下:

repeat
    命令序列;
until 条件 end repeat;

例子:定义一个存储过程,显示100-999之间的水仙花数。水仙花数是指每一位数的三次方的和等于该数(例如:153=13+53+3^3)。

delimiter //
create procedure sp_sxh() no sql
begin
    declare bai int;
    declare shi int;
    declare ge int;
    declare n int default 100;
    repeat 
        set bai:=floor(n/100);
        set shi:=floor((n-bai*100)/10);
        set ge:=n-bai*100-shi*10;
        if power(bai,3)+power(shi,3)+power(ge,3)=n then
        	select n;
        end if;
        set n:=n+1;
    until n>999 end repeat;
end //
delimiter ;

调用以上存储过程,查询结果如下:

mysql> call sp_sxh();
+------+
| n    |
+------+
|  153 |
+------+
1 row in set (0.01 sec)

+------+
| n    |
+------+
|  370 |
+------+
1 row in set (0.02 sec)

+------+
| n    |
+------+
|  371 |
+------+
1 row in set (0.02 sec)

+------+
| n    |
+------+
|  407 |
+------+
1 row in set (0.02 sec)

Query OK, 0 rows affected (0.05 sec)
发布了44 篇原创文章 · 获赞 48 · 访问量 5388

猜你喜欢

转载自blog.csdn.net/weixin_44377973/article/details/103770635
今日推荐