当前位置: 首页 > news >正文

【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)
BEGINIF score >= 90 THENSELECT '优秀' AS level;ELSEIF score >= 80 THENSELECT '良好' AS level;ELSEIF score >= 60 THENSELECT '及格' AS level;ELSESELECT '不及格' 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)
BEGINCASE dayWHEN 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(基于条件判断)

CASEWHEN 条件1 THEN 语句1;WHEN 条件2 THEN 语句2;ELSE 其他语句;
END CASE;
示例:判断年龄阶段
DELIMITER $$CREATE PROCEDURE CheckAgeGroup(IN age INT)
BEGINCASEWHEN 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)
BEGINDECLARE i INT DEFAULT 1;SET result = 0;WHILE i <= n DOSET 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()
BEGINDECLARE i INT DEFAULT 1;REPEATSELECT i; -- 每次输出当前 iSET i = i + 1;UNTIL i > 5END 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)
BEGINDECLARE i INT DEFAULT 1;SET result = 0;sum_loop: LOOPIF i > n THENLEAVE sum_loop; -- 相当于 breakEND 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: LOOPinner_loop: WHILE i < 10 DOIF condition THENLEAVE outer_loop; -- 直接跳出外层循环END IF;END WHILE inner_loop;
END LOOP outer_loop;

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


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

DELIMITER $$CREATE PROCEDURE FibSequence(IN n INT)
BEGINDECLARE a INT DEFAULT 0;DECLARE b INT DEFAULT 1;DECLARE i INT DEFAULT 1;DECLARE temp INT;IF n <= 0 THENSELECT '请输入正整数' AS msg;ELSEWHILE i <= n DOSELECT 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
http://www.dtcms.com/a/351934.html

相关文章:

  • SQL server 触发器的使用
  • PostgreSQL诊断系列(4/6):表空间与膨胀分析——解决“越用越大”的存储难题
  • woocommerce后台一次搜索多个ID订单的实现方法
  • 两周年创作纪念,忆笑傲江湖岁月
  • 探寻跨语言统一真理及其对NLP的未来启示
  • 项目管理软件与 Excel:哪个适合您的团队?
  • 超越MySQL:TDengine的时序数据处理革新与实践指南
  • [新启航]新启航激光频率梳 “光量子透视”:2μm 精度破除遮挡,完成 130mm 深孔 3D 建模
  • 在线提取维基百科Wikipedia文章页面及离线批处理Wikipedia XML Dump文件
  • 抽签占卜抖音快手微信小程序看广告流量主开源
  • 6.6 Element UI 加载指示器
  • 机器学习每日一题000-矩阵和向量的乘法python实现
  • Linux SSH 基于密钥交换的自动登录原理简介及配置说明
  • 数据结构第7章 查找(竟成)
  • 在 OpenLayers 中实现自定义右键菜单:基于 vue3-context-menu 的完整指南
  • 河南河北到底以哪条河为界?是黄河还是漳河呢?
  • 你真的了解操作系统吗?
  • 低代码开发实践:快速构建企业采购审批流程的技术方案
  • 无线网络中的Duration字段计算:原理、机制与实现
  • php内存缓存插件yac的安装配置--平替apcu,多进程共享内存
  • 均胜电子上半年毛利率持续提升,汽车智能化与机器人业务多点突破
  • sed流编辑:从ed到现代文本处理的进化
  • 第二篇:MySQL初始化配置与性能优化
  • 汽车零部件软件迭代开发指南
  • Spring Boot -Mybatis的使用和基础
  • 数字孪生:工厂优化的下一个前沿领域
  • GIS开源库汇总
  • Linux笔记10——shell编程基础-4
  • Web安全开发指导规范文档V1.0
  • 基于SpringBoot的美剧观影网站【2026最新】