# 流程控制

# 一、分支结构之 IF

IF val IS NULL
    THEN SELECT 'val is null';
ELSE SELECT 'val is not null';
END IF;
1
2
3
4

声明存储过程“update_salary_by_eid2”,定义IN参数emp_id,输入员工编号。判断该员工 薪资如果低于9000元并且入职时间超过5年,就涨薪500元;否则就涨薪100元。

DELIMITER //
CREATE PROCEDURE update_salary_by_eid2(IN emp_id INT)
BEGIN
    DECLARE emp_salary DOUBLE;
    DECLARE hire_year DOUBLE;
    SELECT salary INTO emp_salary FROM employees WHERE employee_id = emp_id;
    SELECT DATEDIFF(CURDATE(),hire_date)/365 INTO hire_year
    FROM employees WHERE employee_id = emp_id;
    IF emp_salary < 8000 AND hire_year > 5
        THEN UPDATE employees SET salary = salary + 500 WHERE employee_id =
emp_id;
    ELSE
        UPDATE employees SET salary = salary + 100 WHERE employee_id = emp_id;
END IF; END //
DELIMITER ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

声明存储过程“update_salary_by_eid3”,定义IN参数emp_id,输入员工编号。判断该员工 薪资如果低于9000元,就更新薪资为9000元;薪资如果大于等于9000元且低于10000的,但是奖金 比例为NULL的,就更新奖金比例为0.01;其他的涨薪100元。

DELIMITER //
 CREATE PROCEDURE update_salary_by_eid3(IN emp_id INT)
 BEGIN
     DECLARE emp_salary DOUBLE;
     DECLARE bonus DECIMAL(3,2);
     SELECT salary INTO emp_salary FROM employees WHERE employee_id = emp_id;
     SELECT commission_pct INTO bonus FROM employees WHERE employee_id = emp_id;
     IF emp_salary < 9000
        THEN UPDATE employees SET salary = 9000 WHERE employee_id = emp_id;
    ELSE
        UPDATE employees SET salary = salary + 100 WHERE employee_id = emp_id;
END IF; END //
DELIMITER ;
1
2
3
4
5
6
7
8
9
10
11
12
13

# 二、分支结构之 CASE

使用CASE流程控制语句的第1种格式,判断val值等于1、等于2,或者两者都不等。

CASE val
   WHEN 1 THEN SELECT 'val is 1';    
   WHEN 2 THEN SELECT 'val is 2';    
   ELSE SELECT 'val is not 1 or 2'; 
END CASE;
1
2
3
4
5

使用CASE流程控制语句的第2种格式,判断val是否为空、小于0、大于0或者等于0。

CASE
    WHEN val IS NULL THEN SELECT 'val is null';
    WHEN val < 0 THEN SELECT 'val is less than 0';
    WHEN val > 0 THEN SELECT 'val is greater than 0';
    ELSE SELECT 'val is 0';
END CASE;
1
2
3
4
5
6

声明存储过程“update_salary_by_eid4”,定义IN参数emp_id,输入员工编号。判断该员工 薪资如果低于9000元,就更新薪资为9000元;薪资大于等于9000元且低于10000的,但是奖金比例 为NULL的,就更新奖金比例为0.01;其他的涨薪100元。

DELIMITER //
BEGIN
    DECLARE emp_sal DOUBLE;
    DECLARE bonus DECIMAL(3,2);
    SELECT salary INTO emp_sal FROM employees WHERE employee_id = emp_id;
    SELECT commission_pct INTO bonus FROM employees WHERE employee_id = emp_id;
    CASE
    WHEN emp_sal<9000
        THEN UPDATE employees SET salary=9000 WHERE employee_id = emp_id;
    WHEN emp_sal<10000 AND bonus IS NULL
        THEN UPDATE employees SET commission_pct=0.01 WHERE employee_id = emp_id;
    ELSE
        UPDATE employees SET salary=salary+100 WHERE employee_id = emp_id;
    END CASE;
END //
DELIMITER ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

声明存储过程update_salary_by_eid5,定义IN参数emp_id,输入员工编号。判断该员工的 入职年限,如果是0年,薪资涨50;如果是1年,薪资涨100;如果是2年,薪资涨200;如果是3年, 薪资涨300;如果是4年,薪资涨400;其他的涨薪500。

DELIMITER //
CREATE PROCEDURE update_salary_by_eid5(IN emp_id INT)
BEGIN
    DECLARE emp_sal DOUBLE;
    DECLARE hire_year DOUBLE;
    SELECT salary INTO emp_sal FROM employees WHERE employee_id = emp_id;
    SELECT ROUND(DATEDIFF(CURDATE(),hire_date)/365) INTO hire_year FROM employees
WHERE employee_id = emp_id;
    CASE hire_year
        WHEN 0 THEN UPDATE employees SET salary=salary+50 WHERE employee_id = emp_id;
        WHEN 1 THEN UPDATE employees SET salary=salary+100 WHERE employee_id = emp_id;
        WHEN 2 THEN UPDATE employees SET salary=salary+200 WHERE employee_id = emp_id;
        WHEN 3 THEN UPDATE employees SET salary=salary+300 WHERE employee_id = emp_id;
        WHEN 4 THEN UPDATE employees SET salary=salary+400 WHERE employee_id = emp_id;
        ELSE UPDATE employees SET salary=salary+500 WHERE employee_id = emp_id;
    END CASE;
END //
DELIMITER ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 三、循环结构之LOOP

使用LOOP语句进行循环操作,id值小于10时将重复执行循环过程。

DECLARE id INT DEFAULT 0;
add_loop:LOOP
    SET id = id +1;
    IF id >= 10 THEN LEAVE add_loop;
    END IF;
END LOOP add_loop;
1
2
3
4
5
6

当市场环境变好时,公司为了奖励大家,决定给大家涨工资。声明存储过程 “update_salary_loop()”,声明OUT参数num,输出循环次数。存储过程中实现循环给大家涨薪,薪资涨为 原来的1.1倍。直到全公司的平均薪资达到12000结束。并统计循环次数。

DELIMITER //
CREATE PROCEDURE update_salary_loop(OUT num INT)
BEGIN
    DECLARE avg_salary DOUBLE;
    DECLARE loop_count INT DEFAULT 0;
    SELECT AVG(salary) INTO avg_salary FROM employees;
    label_loop:LOOP
        IF avg_salary >= 12000 THEN LEAVE label_loop;
        END IF;
        UPDATE employees SET salary = salary * 1.1;
        SET loop_count = loop_count + 1;
        SELECT AVG(salary) INTO avg_salary FROM employees;
    END LOOP label_loop;
    SET num = loop_count;
END //
DELIMITER ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

四、循环结构之WHILE

DELIMITER //
CREATE PROCEDURE test_while()
BEGIN
    DECLARE i INT DEFAULT 0;
    WHILE i < 10 DO
        SET i = i + 1;
    END WHILE;
    SELECT i;
END //
DELIMITER ;
#调用
CALL test_while();
1
2
3
4
5
6
7
8
9
10
11
12

市场环境不好时,公司为了渡过难关,决定暂时降低大家的薪资。声明存储过程 “update_salary_while()”,声明OUT参数num,输出循环次数。存储过程中实现循环给大家降薪,薪资降 为原来的90%。直到全公司的平均薪资达到5000结束。并统计循环次数。

DELIMITER //
CREATE PROCEDURE update_salary_while(OUT num INT)
BEGIN
    DECLARE avg_sal DOUBLE ;
    DECLARE while_count INT DEFAULT 0;
    SELECT AVG(salary) INTO avg_sal FROM employees;
    WHILE avg_sal > 5000 DO
        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 ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 四、循环结构之REPEAT

REPEAT语句创建一个带条件判断的循环过程。与WHILE循环不同的是,REPEAT 循环首先会执行一次循 环,然后在 UNTIL 中进行表达式的判断,如果满足条件就退出,即 END REPEAT;如果条件不满足,则会 就继续执行循环,直到满足退出条件为止。

DELIMITER //
CREATE PROCEDURE test_repeat()
BEGIN
    DECLARE i INT DEFAULT 0;
    REPEAT
        SET i = i + 1;
    UNTIL i >= 10
    END REPEAT;
    SELECT i;
END //
DELIMITER ;
1
2
3
4
5
6
7
8
9
10
11

当市场环境变好时,公司为了奖励大家,决定给大家涨工资。声明存储过程 “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 ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

五、跳转语句之LEAVE语句

创建存储过程 “leave_begin()”,声明INT类型的IN参数num。给BEGIN...END加标记名,并在 BEGIN...END中使用IF语句判断num参数的值。

  • 如果num<=0,则使用LEAVE语句退出BEGIN...END;
  • 如果num=1,则查询“employees”表的平均薪资;
  • 如果num=2,则查询“employees”表的最低薪资;
  • 如果num>2,则查询“employees”表的最高薪资。

IF语句结束后查询“employees”表的总人数。

DELIMITER //
CREATE PROCEDURE leave_begin(IN num INT)
    begin_label: BEGIN
        IF num<=0
            THEN LEAVE begin_label;
        ELSEIF num=1
            THEN SELECT AVG(salary) FROM employees;
        ELSEIF num=2
            THEN SELECT MIN(salary) FROM employees;
        ELSE
            SELECT MAX(salary) FROM employees;
        END IF;
        SELECT COUNT(*) FROM employees;
    END //
DELIMITER ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

当市场环境不好时,公司为了渡过难关,决定暂时降低大家的薪资。声明存储过程“leave_while()”,声明 OUT参数num,输出循环次数,存储过程中使用WHILE循环给大家降低薪资为原来薪资的90%,直到全公 司的平均薪资小于等于10000,并统计循环次数。

DELIMITER //
CREATE PROCEDURE leave_while(OUT num INT)
BEGIN
#
DECLARE avg_sal DOUBLE;#记录平均工资
SELECT AVG(salary) INTO avg_sal FROM employees; #1 初始化条件 
while_label:WHILE TRUE DO #2 循环条件

#3 循环体
IF avg_sal <= 10000 THEN
            LEAVE while_label;
        END IF;
        UPDATE employees SET salary  = salary * 0.9;
        SET while_count = while_count + 1;
#4 迭代条件
SELECT AVG(salary) INTO avg_sal FROM employees;
END WHILE; #赋值
    SET num = while_count;
END //
DELIMITER ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 五、跳转语句之ITERATE语句

ITERATE语句:只能用在循环语句(LOOP、REPEAT和WHILE语句)内,表示重新开始循环,将执行顺序 转到语句段开头处。如果你有面向过程的编程语言的使用经验,你可以把 ITERATE 理解为 continue,意 思为“再次循环”。

定义局部变量num,初始值为0。循环结构中执行num + 1操作。

  • 如果num < 10,则继续执行循环;
  • 如果num > 15,则退出循环结构;
DELIMITER //
CREATE PROCEDURE test_iterate()
BEGIN
    DECLARE num INT DEFAULT 0;
    my_loop:LOOP
        SET num = num + 1;
        IF num < 10
            THEN ITERATE my_loop;
ELSEIF num > 15
THEN LEAVE my_loop;
        END IF;
SELECT '让天下没有难学的技术'; END LOOP my_loop;
END //
DELIMITER ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
更新时间: 11/23/2021, 2:19:33 PM