【SQL】深入理解MySQL存储过程:MySQL流程控制语句详解

一、前置知识

  • 流程控制语句只能在 BEGIN ... END 块中使用。
  • 常用于实现条件判断、循环处理等逻辑。
  • 需要配合变量使用(如 DECLARE 声明变量,SET 赋值)。
DELIMITER $$

CREATE PROCEDURE 示例流程控制()
BEGIN
    -- 在这里使用 IF、CASE、WHILE 等语句
END$$

DELIMITER ;

二、1. IF 语句 —— 条件判断

✅ 语法结构:

IF 条件 THEN
    语句1;
[ELSEIF 条件2 THEN
    语句2;]
[ELSE
    其他语句;]
END IF;

🔍 示例:根据成绩判断等级

DELIMITER $$

CREATE PROCEDURE GetGrade(IN score INT)
BEGIN
    IF score >= 90 THEN
        SELECT '优秀' AS level;
    ELSEIF score >= 80 THEN
        SELECT '良好' AS level;
    ELSEIF score >= 60 THEN
        SELECT '及格' AS level;
    ELSE
        SELECT '不及格' AS level;
    END IF;
END$$

DELIMITER ;

-- 调用
CALL GetGrade(85); -- 输出:良好

二、2. CASE 语句 —— 多分支选择

有两种形式:简单 CASE搜索型 CASE

✅ 形式一:简单 CASE(类似 switch)

CASE 变量
    WHEN1 THEN 语句1;
    WHEN2 THEN 语句2;
    ELSE 其他语句;
END CASE;
示例:根据数字输出星期名称
DELIMITER $$

CREATE PROCEDURE GetWeekday(IN day INT)
BEGIN
    CASE day
        WHEN 1 THEN SELECT '星期一' AS weekday;
        WHEN 2 THEN SELECT '星期二' AS weekday;
        WHEN 3 THEN SELECT '星期三' AS weekday;
        ELSE SELECT '未知' AS weekday;
    END CASE;
END$$

DELIMITER ;

CALL GetWeekday(2); -- 输出:星期二

✅ 形式二:搜索型 CASE(基于条件判断)

CASE
    WHEN 条件1 THEN 语句1;
    WHEN 条件2 THEN 语句2;
    ELSE 其他语句;
END CASE;
示例:判断年龄阶段
DELIMITER $$

CREATE PROCEDURE CheckAgeGroup(IN age INT)
BEGIN
    CASE
        WHEN age < 13 THEN SELECT '儿童' AS group_name;
        WHEN age BETWEEN 13 AND 17 THEN SELECT '青少年';
        WHEN age BETWEEN 18 AND 65 THEN SELECT '成年人';
        ELSE SELECT '老年人';
    END CASE;
END$$

DELIMITER ;

CALL CheckAgeGroup(25); -- 输出:成年人

💡 提示:CASE 更适合多分支选择,代码更清晰。


三、循环结构概述

MySQL 支持三种循环结构:

循环类型特点
WHILE先判断条件,再执行(可能一次都不执行)
REPEAT先执行一次,再判断是否继续(至少执行一次)
LOOP无条件循环,需手动 LEAVE 退出

所有循环都可通过 ITERATE(继续)和 LEAVE(跳出)控制流程。


三、1. WHILE 循环 —— 当型循环

✅ 语法:

[label:] WHILE 条件 DO
    循环体语句;
END WHILE [label];

🔍 示例:计算 1 到 n 的和

DELIMITER $$

CREATE PROCEDURE SumToN(IN n INT, OUT result INT)
BEGIN
    DECLARE i INT DEFAULT 1;
    SET result = 0;

    WHILE i <= n DO
        SET result = result + i;
        SET i = i + 1;
    END WHILE;
END$$

DELIMITER ;

-- 调用
CALL SumToN(100, @sum);
SELECT @sum; -- 输出:5050

三、2. REPEAT 循环 —— 直到型循环(类似 do-while)

✅ 语法:

[label:] REPEAT
    循环体语句;
UNTIL 条件
END REPEAT [label];

⚠️ 注意:UNTIL 后的条件为 真时退出循环

🔍 示例:打印数字直到大于 5

DELIMITER $$

CREATE PROCEDURE PrintUntil5()
BEGIN
    DECLARE i INT DEFAULT 1;
    REPEAT
        SELECT i; -- 每次输出当前 i
        SET i = i + 1;
    UNTIL i > 5
    END REPEAT;
END$$

DELIMITER ;

CALL PrintUntil5();
-- 输出 1, 2, 3, 4, 5 (每次 SELECT 一行)

三、3. LOOP 循环 —— 手动控制的无限循环

✅ 语法:

[label:] LOOP
    循环体语句;
    -- 必须有 LEAVE 或 ITERATE
END LOOP [label];

控制关键字:

  • LEAVE label:相当于 break,跳出循环
  • ITERATE label:相当于 continue,跳回循环开头

🔍 示例:使用 LOOP 计算 1~100 的和

DELIMITER $$

CREATE PROCEDURE SumWithLoop(IN n INT, OUT result INT)
BEGIN
    DECLARE i INT DEFAULT 1;
    SET result = 0;

    sum_loop: LOOP
        IF i > n THEN
            LEAVE sum_loop; -- 相当于 break
        END IF;

        SET result = result + i;
        SET i = i + 1;
    END LOOP sum_loop;
END$$

DELIMITER ;

CALL SumWithLoop(100, @res);
SELECT @res; -- 输出:5050

四、高级技巧:标签(Label)与流程跳转

使用标签提升可读性与控制力

outer_loop: LOOP
    inner_loop: WHILE i < 10 DO
        IF condition THEN
            LEAVE outer_loop; -- 直接跳出外层循环
        END IF;
    END WHILE inner_loop;
END LOOP outer_loop;

✅ 标签命名建议:loop_nameexit_loopcontinue_loop 等,增强可读性。


五、综合实战:生成斐波那契数列前 N 项

DELIMITER $$

CREATE PROCEDURE FibSequence(IN n INT)
BEGIN
    DECLARE a INT DEFAULT 0;
    DECLARE b INT DEFAULT 1;
    DECLARE i INT DEFAULT 1;
    DECLARE temp INT;

    IF n <= 0 THEN
        SELECT '请输入正整数' AS msg;
    ELSE
        WHILE i <= n DO
            SELECT a AS fibonacci; -- 输出当前项
            SET temp = a + b;
            SET a = b;
            SET b = temp;
            SET i = i + 1;
        END WHILE;
    END IF;
END$$

DELIMITER ;

CALL FibSequence(8);
-- 输出:0, 1, 1, 2, 3, 5, 8, 13

六、常见错误与注意事项

错误解决方法
忘记 DELIMITER 导致语法错误使用 DELIMITER $$ 避免 ; 提前结束
变量未声明使用 DECLAREBEGIN 后第一行声明
循环未设置退出条件导致死循环(MySQL 会超时中断)
CASE 缺少 END CASE语法错误,必须配对
在函数中使用 SELECT 直接输出结果集❌ 函数不能返回结果集,只能返回单值

七、总结对比表

语句用途是否必须结束条件类似语言中的
IF条件分支if-else
CASE多分支选择switch / if-elif
WHILE先判断后执行while
REPEAT先执行后判断do-while
LOOP自定义循环手动 LEAVEfor(;😉 / goto
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值