文章目录
- 一、循环结构之 LOOP
- 二、循环结构之 WHILE
- 三、循环结构之 REPEAT
- 四、跳转语句之LEAVE语句
- 五、跳转语句之ITERATE语句
一、循环结构之 LOOP
LOOP 循环语句用来重复执行某些语句。LOOP 内的语句一直重复执行直到循环被退出(使用 LEAVE 子句),跳出循环过程。LOOP 语句的基本格式如下:
-- loop_label表示LOOP语句的标注名称,该参数可以省略
[loop_label:] LOOP
-- 循环执行的语句
END LOOP [loop_label]
举例1:使用 LOOP 语句进行循环操作,id值小于10时将重复执行循环过程。
DELIMITER //
CREATE PROCEDURE test_loop()
BEGIN
DECLARE id INT DEFAULT 0;
add_loop:LOOP
IF id < 10 THEN SET id = id + 1;
ELSE
LEAVE add_loop;
END IF;
END LOOP add_loop;
SELECT id;
END //
DELIMITER ;
CALL test_loop();
举例2:应用LOOP语句求前100项的和。首先定义变量i和s,分别用来控制循环的次数和保存前100项的和,进入该循环体后首先使s的值加i,之后使i加1并进入下次循环,直到i大于100,通过LEAVE语句退出循环并输出结果。
DROP PROCEDURE get_sum;
DELIMITER //
CREATE PROCEDURE get_sum(OUT result INT)
BEGIN
DECLARE i INT DEFAULT 1;
DECLARE s INT DEFAULT 0;
get_sum_loop: LOOP
SET s = s + i;
IF i >= 100 THEN LEAVE get_sum_loop;
END IF;
SET i = i + 1;
END LOOP get_sum_loop;
SET result = s;
END //
DELIMITER ;
CALL get_sum(@s);
SELECT @s;
举例3:当市场环境变好时,公司为了奖励大家,决定给大家涨工资。声明存储过程 update_salary_loop()
,声明OUT参数num,输出循环次数。存储过程中实现循环给大家涨薪,薪资涨为原来的1.1倍。直到全公司的平均薪资达到12000结束。并统计循环次数。
DROP PROCEDURE update_salary_loop;
DELIMITER //
CREATE PROCEDURE update_salary_loop(OUT num INT)
BEGIN
DECLARE emp_avg_sal DOUBLE;
DECLARE count_ INT DEFAULT 0;
SELECT AVG(salary) INTO emp_avg_sal FROM employees;
avg_salary_loop: LOOP
IF emp_avg_sal > 12000
THEN LEAVE avg_salary_loop;
END IF;
UPDATE employees SET salary = salary * 1.1;
SET count_ = count_ + 1;
SELECT AVG(salary) INTO emp_avg_sal FROM employees;
END LOOP avg_salary_loop;
SET num = count_;
END //
DELIMITER ;
CALL update_salary_loop(@x);
SELECT @x;
SELECT AVG(salary) FROM employees;
二、循环结构之 WHILE
WHILE 语句创建一个带条件判断的循环过程。WHILE 在执行语句执行时,先对指定的表达式进行判断,如果为真,就执行循环内的语句,否则退出循环。WHILE 语句的基本格式如下:
[while_label:] WHILE 循环条件 DO
循环体
END WHILE [while_label];
while_label 为 WHILE 语句的标注名称;如果循环条件结果为真,WHILE 语句内的语句或语句群被执行,直至循环条件为假,退出循环。
举例1:应用WHILE语句求前50项的和。首先定义变量i和s,分别用来控制循环的次数和保存前50项和,当变量i的值小于或等于50时,使s的值加i,并同时使i的值增1。直到i大于50时退出循环并输出结果。
DROP PROCEDURE test_while;
DELIMITER //
CREATE PROCEDURE test_while(OUT num INT)
BEGIN
DECLARE i,s INT DEFAULT 0;
while_label: WHILE i <= 50 DO
SET s = s + i;
SET i = i + 1;
END WHILE while_label;
SET num = s;
END //
DELIMITER ;
CALL test_while(@x);
SELECT @x;
举例2:市场环境不好时,公司为了渡过难关,决定暂时降低大家的薪资。声明存储过程 update_salary_while()
,声明OUT参数num,输出循环次数。存储过程中实现循环给大家降薪,薪资降为原来的90%。直到全公司的平均薪资达到5000结束。并统计循环次数。
DROP PROCEDURE update_salary_while;
DELIMITER //
CREATE PROCEDURE update_salary_while(OUT num INT)
BEGIN
DECLARE avg_sal DOUBLE;
DECLARE `count` INT DEFAULT 0;
SELECT AVG(salary) INTO avg_sal FROM employees;
-- while_label: WHILE avg_sal > 5000 DO
while_label: WHILE TRUE DO
IF avg_sal <= 5000
THEN LEAVE while_label;
END IF;
UPDATE employees SET salary = salary * 0.9;
SET `count` = `count` + 1;
SELECT AVG(salary) INTO avg_sal FROM employees;
END WHILE while_label;
SET num = `count`;
END //
DELIMITER ;
CALL update_salary_while(@x);
SELECT @x;
SELECT AVG(salary) FROM employees;
三、循环结构之 REPEAT
REPEAT 语句创建一个带条件判断的循环过程。与 WHILE 循环不同的是,REPEAT 循环首先会执行一次循环,然后在 UNTIL 中进行表达式的判断,如果满足条件就退出,即 END REPEAT;如果条件不满足,则会就继续执行循环,直到满足退出条件为止。REPEAT语句的基本格式如下:
[repeat_label:] REPEAT
循环体的语句
UNTIL 结束循环的条件表达式 END REPEAT [repeat_label]
repeat_label 为 REPEAT 语句的标注名称,该参数可以省略;REPEAT 语句内的语句或语句群被重复,直至 expr_condition 为真。
举例1:应用REPEAT语句求前100项的和。首先定义变量i和s,分别用来控制循环的次数和保存前100项和,进入循环体后首先使s的值加i,之后使i的值加1,直到i大于100时退出循环并输出结果。
DELIMITER //
CREATE PROCEDURE test_repeat(OUT num INT)
BEGIN
DECLARE i,s INT DEFAULT 0;
repeat_label: REPEAT
SET s = s + i;
SET i = i + 1;
UNTIL i > 100 END REPEAT repeat_label;
SET num = s;
END //
DELIMITER ;
CALL test_repeat(@s);
SELECT @s;
举例2:当市场环境变好时,公司为了奖励大家,决定给大家涨工资。声明存储过程 update_salary_repeat()
,声明OUT参数num,输出循环次数。存储过程中实现循环给大家涨薪,薪资涨为原来的1.15倍。直到全公司的平均薪资达到13000结束。并统计循环次数。
DELIMITER //
CREATE PROCEDURE update_salary_repeat(OUT num INT)
BEGIN
DECLARE avg_sal DOUBLE ;
DECLARE repeat_count INT DEFAULT 0;
SELECT AVG(salary) INTO avg_sal FROM employees;
REPEAT
UPDATE employees SET salary = salary * 1.15;
SET repeat_count = repeat_count + 1;
SELECT AVG(salary) INTO avg_sal FROM employees;
UNTIL avg_sal >= 13000 END REPEAT;
SET num = repeat_count;
END //
DELIMITER ;
对比三种循环结构:
- 这三种循环都可以省略名称,但如果循环中添加了循环控制语句(LEAVE或ITERATE)则必须添加名称。
- LOOP:一般用于实现简单的"死"循环,WHILE:先判断后执行,REPEAT:先执行后判断,无条件至少执行一次。
四、跳转语句之LEAVE语句
LEAVE 语句:可以用在循环语句内,或者以 BEGIN 和 END 包裹起来的程序体内,表示跳出循环或者跳出程序体的操作。如果你有面向过程的编程语言的使用经验,你可以把 LEAVE 理解为 break。基本格式如下:
LEAVE 标记名
其中,label 参数表示循环的标志。LEAVE 和 BEGIN … END 或循环一起被使用。举例1:创建存储过程 leave_begin()
,声明INT类型的IN参数num。给BEGIN…END加标记名,并在BEGIN…END中使用IF语句判断num参数的值。IF语句结束后查询 employees 表的总人数。
如果num<=0,则使用LEAVE语句退出BEGIN...END
如果num=1,则查询 employees 表的平均薪资
如果num=2,则查询 employees 表的最低薪资
如果num>2,则查询 employees 表的最高薪资
示例:
DELIMITER //
CREATE PROCEDURE leave_begin(IN num INT)
leave_label: BEGIN
IF num <=0
THEN LEAVE leave_label;
ELSEIF num = 1
THEN SELECT AVG(salary) FROM employees;
ELSEIF num = 2
THEN SELECT MIN(salary) FROM employees;
ELSEIF num > 2
THEN SELECT MAX(salary) FROM employees;
SELECT COUNT(*) FROM employees;
END IF;
END //
DELIMITER ;
CALL leave_begin(3);
举例2:当市场环境不好时,公司为了渡过难关,决定暂时降低大家的薪资。声明存储过程 leave_while(),声明OUT参数num,输出循环次数,存储过程中使用WHILE循环给大家降低薪资为原来薪资的90%,直到全公司的平均薪资小于等于10000,并统计循环次数。
DELIMITER //
CREATE PROCEDURE leave_while(OUT num INT)
BEGIN
DECLARE avg_sal DOUBLE; #记录平均工资
DECLARE while_count INT DEFAULT 0; #记录循环次数
SELECT AVG(salary) INTO avg_sal FROM employees; #① 初始化条件
while_label: WHILE TRUE DO #② 循环条件
#③ 循环体
IF avg_sal <= 10000 THEN
LEAVE while_label;
END IF;
UPDATE employees SET salary = salary * 0.9;
SET while_count = while_count + 1;
#④ 迭代条件
SELECT AVG(salary) INTO avg_sal FROM employees;
END WHILE;
#赋值
SET num = while_count;
END //
DELIMITER ;
五、跳转语句之ITERATE语句
ITERATE语句:只能用在循环语句(LOOP、REPEAT和WHILE语句)内,表示重新开始循环,将执行顺序转到语句段开头处。如果你有面向过程的编程语言的使用经验,你可以把 ITERATE 理解为 continue,意思为 再次循环。 语句基本格式如下:
ITERATE label
label 参数表示循环的标志。ITERATE 语句必须跟在循环标志前面。举例: 求出10以内的偶数和;
DELIMITER //
CREATE PROCEDURE test_iterate()
BEGIN
DECLARE num1,result INT DEFAULT 0;
my_while: WHILE num1 < 10 DO
IF num1 > 10
THEN ITERATE my_while;
END IF;
IF num1 % 2 = 0
THEN SET result = result + num1;
END IF;
SET num1 = num1 + 1;
END WHILE my_while;
SELECT result;
END //
DELIMITER ;
CALL test_iterate(); -- 20
至此今天的学习就到此结束了