新闻详情

新闻详情

首页 / 资讯中心 / 详情

MySQL进阶|游标与条件处理程序:存储过程逐行捕获异常

发布时间:2026/9/27 5:57:34来源:尧图网络
MySQL进阶|游标与条件处理程序:存储过程逐行捕获异常
博客主页小谢同学的小破站✍️本文由小谢同学的小破站原创首发于 CSDN ☕JavaSE专栏JavaSEJavaEE初阶专栏JavaEE初阶JavaEE进阶专栏JavaEE进阶数据结构专栏数据结构⚙️算法专栏算法MySQL初阶专栏MySQL初阶MySQL进阶专栏MySQL进阶计算机网络专栏计算机网络C语言专栏C语言欢迎点赞 收藏⭐ 留言发现错误欢迎指正✨脚踏实地持续深耕奔赴自己的目标✨----- 分割线 -------游标与条件处理程序1. 游标cursor1.1 游标完整四步声明、open、fetch、close1.2 游标基础示例代码1.3 游标缺点内存、不适合大表2. 条件处理程序 HANDLER2.1 语法讲解 DECLARE … HANDLER2.2 游标必踩坑fetch读完数据报1329报错HANDLER处理结束标记2.3 HANDLER的触发时机、continue和exit区别3. 条件处理程序 HANDLER3.1 游标 条件处理程序完整可运行存储过程(逐行遍历表并退出~)前言这里是小谢同学整理有关MySQL中游标的概念。笔记用于自我复盘巩固有错误欢迎大家指出专栏还有 Java、网络、C 语言系列笔记欢迎翻阅.同时也希望这篇文章能够帮助到你~1. 游标cursorMySQL 游标是一种数据库对象用于在存储过程或函数中逐行遍历查询结果集以便对每条记录进行处理。游标Cursor不是单独的 SELECT 语句而是由 SELECT 查询返回的结果集的指针。它允许程序逐行访问数据而不是一次性处理整个结果集这在处理大量数据或需要对每行执行复杂逻辑时非常有用MySQL 中的游标只能在存储过程和函数中使用。1.1 游标完整四步声明、open、fetch、close游标必须在条件处理程序之前被声明,并且变量必须在游标活条件处理程序之前被声明例如:我们想在一个存储过程中定义变量,我们需要在写存储过程中最前面先定义出我们所需要的变量如果后续我们想要添加某一个变量,我们可以直接在没有创建存储过程之前来添加,方便进行统一管理变量-游标-条件处理语句语法:-- 1.声明游标DECLAREcursor_nameCURSORFORselect_statement;-- 2.打开游标OPENcursor_name;-- 3.读取一行FETCHcursor_nameINTOvar_name[,var_name]...;-- 4.关闭游标CLOSEcursor_name;解释select_statement: 查询语句cursor_name : 游标名称var_name 读取对应的字段var_name [, var_name] … :查询放入的变量1.2 游标基础示例代码例如:传入班级编号,查询学生表中属于该班级学生的信息,并将符合条件的学生信息写入一张新表中;新表及字段t_student_class(id,student_name,class_name)实现逻辑:定义变量来接收查询结果集中的每一列的值声明游标创建新表开启游标从游标中获取结果集中的记录插入新表关闭游标对应表的查询结果:class:student:DELIMITER//CREATEPROCEDUREp7(INclass_idINT)BEGIN-- 创建我们所需要的变量-- 学生姓名DECLAREstudent_nameVARCHAR(20);-- 班级名字DECLAREclass_namevarchar(20);-- 声明游标DECLAREs_cursorCURSORFORSELECTs.name,ds.nameFROMstudentASsJOINclassASdsONs.class_idds.idwhereds.idclass_id;-- 创建新表CREATETABLEIFNOTEXISTSt_student_class(idINTPRIMARYKEYAUTO_INCREMENT,student_nameVARCHAR(20),class_nameVARCHAR(20));-- 打开游标OPENs_cursor;WHILETRUEDO-- 获取游标的内容FETCHs_cursorINTOstudent_name,class_name;-- 插入新表INSERTINTOt_student_classVALUES(null,student_name,class_name);ENDWHILE;END//DELIMITER;CALLp7(1);此处报错了:1329的典型错误由于while循环的退出条件是true此时是⼀个死循环当游标遍历完成之后继续向后遍历发现没有记录所以报错可以通过条件处理程序解决我们此时怎么解决这个问题?答案: 条件处理程序 HANDLER1.3 游标缺点内存、不适合大表消耗内存OPEN 的时候会把全部查询结果集加载到内存数据越多占用内存越高。性能差不适合大表游标是逐行处理行越多速度越慢千万级大表严禁游标。MySQL 设计优先集合操作能用UPDATE / INSERT ... SELECT批量就不要游标逐行。只能在存储过程、存储函数内部使用SQL 语句不能直接写游标。 返回目录2. 条件处理程序 HANDLER定义条件:事先定义程序执行过程中可能遇到的问题处理程序定义了在遇到问题的时候采取的处理方式使⽤条件处理程序保证存储过程或函数在遇到警告或错误时能继续执⾏可以增强程序处理问题的能⼒避免程序异常停⽌运⾏。2.1 语法讲解 DECLARE ... HANDLER语法:DECLAREhandler_actionHANDLERFORcondition_value[,condition_value]...statement;handler_action: {CONTINUE-- 继续执行当前程序|EXIT-- 终止执行当前程序} condition_value: { mysql_error_code-- MySQL错误码|SQLSTATE[VALUE]sqlstate_value-- 状态码|SQLWARNING-- 所有以01开头的SQLSTATE代码|NOTFOUND-- 所有以02开头的SQLSTATE代码|SQLEXCEPTION-- 所有没有被SQLWARNING或NOT FOUND捕获的SQLSTATE代码}mysql_error_code数字错误码SQLSTATE [VALUE] sqlstate_value5 位状态字符串SQLWARNING → 匹配所有01开头 SQLSTATE全部警告类不会终止程序的警告。NOT FOUND → 匹配所有02开头 SQLSTATE(最典型就是02000FETCH 游标已经读到数据集末尾找不到下一行。)SQLEXCEPTION除去 01 开头 (SQLWARNING)、02 开头 (NOT FOUND) 之外剩下全部错误。比如主键冲突、表不存在、语法错误全部归 SQLEXCEPTION。2.2 游标必踩坑fetch读完数据报1329报错HANDLER处理结束标记我们上述所见到的while循环写成死循环的情况,此时就出现了1329错误的状态码;原因归根结底就是:我们没有写条件处理程序而导致程序不能正常执行~2.3 HANDLER的触发时机、continue和exit区别类型行为适用场景CONTINUE捕获异常执行处理代码继续向下跑仅仅记录错误存储过程还要继续执行后续逻辑EXIT捕获异常执行处理代码立刻退出当前 begin‑end 块出错直接结束流程不再执行后面代码触发时机只有执行语句抛出对应条件时才触发 handler不是提前检测。游标 fetch 拿不到数据那一刻触发 NOT FOUND。 返回目录3. 条件处理程序 HANDLER使用条件处理程序来解决while循环出现的问题,防止游标在末尾而出现的问题:DELIMITER//CREATEPROCEDUREp7(INclass_idINT)BEGIN-- 创建我们所需要的变量-- 学生姓名DECLAREstudent_nameVARCHAR(20);-- 班级名字DECLAREclass_namevarchar(20);-- 创建判断条件DECLAREis_doneboolDEFAULTFALSE;-- 声明游标DECLAREs_cursorCURSORFORSELECTs.name,ds.nameFROMstudentASsJOINclassASdsONs.class_idds.idwhereds.idclass_id;-- 创建条件处理程序DECLARECONTINUEHANDLERFORNOTFOUNDSETis_done :TRUE;-- 创建新表CREATETABLEIFNOTEXISTSt_student_class(idINTPRIMARYKEYAUTO_INCREMENT,student_nameVARCHAR(20),class_nameVARCHAR(20));-- 打开游标OPENs_cursor;WHILENOTis_doneDO-- 获取游标的内容FETCHs_cursorINTOstudent_name,class_name;-- 插入新表INSERTINTOt_student_classVALUES(null,student_name,class_name);ENDWHILE;END//DELIMITER;CALLp7(1);SELECT*FROMt_student_class;但是此时问题又来了:为什么最后一条数据出现了两次?SELECTs.name,ds.nameFROMstudentASsJOINclassASdsONs.class_idds.idwhereds.id1;我们明明知道这里只有4条数据,但是为什么出现了5条?原因是:当游标执行到末尾时,再次移动会触发:1329报错,而我们此时处理方式是continue,让程序继续执行,此时游标就会指向最后一行的位置,执行完,然后退出循环此时就出现了,最后一行的数据重复了一次;当然如果我们想要合理的输出结果,我们需要使用LOOP循环来做3.1 游标 条件处理程序完整可运行存储过程(逐行遍历表并退出~)DELIMITER//CREATEPROCEDUREp7(INclass_idINT)BEGIN-- 创建我们所需要的变量-- 学生姓名DECLAREstudent_nameVARCHAR(20);-- 班级名字DECLAREclass_namevarchar(20);-- 创建判断条件DECLAREis_doneboolDEFAULTFALSE;-- 声明游标DECLAREs_cursorCURSORFORSELECTs.name,ds.nameFROMstudentASsJOINclassASdsONs.class_idds.idwhereds.idclass_id;-- 创建条件处理程序DECLARECONTINUEHANDLERFORNOTFOUNDSETis_done :TRUE;-- 创建新表CREATETABLEIFNOTEXISTSt_student_class(idINTPRIMARYKEYAUTO_INCREMENT,student_nameVARCHAR(20),class_nameVARCHAR(20));-- 打开游标OPENs_cursor;read_loop:LOOP-- 获取FETCHs_cursorINTOstudent_name,class_name;IFis_doneTHENLEAVEread_loop;ENDIF;-- 插入数据INSERTINTOt_student_classVALUES(null,student_name,class_name);ENDLOOPread_loop;END//DELIMITER;此时的结果就符合我们预想中的效果了:核心要点复盘DECLARE顺序普通变量 →HANDLER条件处理器 →CURSOR游标顺序颠倒直接语法报错NOT FOUND就是 fetch 读完所有行的信号不要捕获报错退出用标记变量 LEAVE跳出循环游标不要滥用数据库是集合运算尽量用 SQL 批量少用逐行游标逻辑。 返回目录
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

文章02_终稿 2026/9/27 5:57:29

文章02_终稿

为什么 GitHub Copilot 对我们这行没用 AI发展神速,我也来试试AI能在我的工作中帮我做什么。我让AI帮我写一个串口打印调试信息的功能,AI直接插入到接收数据的中断中,结果可想而知,板子不断重启。20多年工业软件从业经历告诉我&am…

阅读更多 →
我用华为云码道 CodeArts 做了个秘钥体检器 2026/9/27 5:57:23

我用华为云码道 CodeArts 做了个秘钥体检器

提交代码前,先查一遍密钥:我用华为云码道 CodeArts 做了个查一下 一键开通华为云码道 CodeArts 代码智能体 一个前端项目做完,页面跑通以后,往往还要整理源码:提交到仓库,发给同事参考,或者作…

阅读更多 →
webpack 模块提取 2026/9/27 5:57:23

webpack 模块提取

保姆级教程:用 AST BFS 精准提取 webpack 模块依赖闭包 摘要:当你手里有一个被 webpack 打包、还做了代码混淆 / 拆 chunk 的前端产物,只想单独运行或逆向分析其中某个入口模块时,面对动辄几千上万个模块该怎么办?本文…

阅读更多 →
AgentENV部署指南:用Docker单机模式最快部署你的沙箱服务器 2026/9/27 5:57:16

AgentENV部署指南:用Docker单机模式最快部署你的沙箱服务器

AgentENV部署指南:用Docker单机模式最快部署你的沙箱服务器 【免费下载链接】AgentENV AgentENV (AENV) is a distributed platform for running agent environments at scale. 项目地址: https://gitcode.com/gh_mirrors/age/AgentENV AgentENV(…

阅读更多 →
5年建站老手揭秘:从零搭建wordpress目录层级避坑指南 2026/9/27 5:57:10

5年建站老手揭秘:从零搭建wordpress目录层级避坑指南

5年建站老手揭秘:从零搭建wordpress目录层级避坑指南 找建站公司怕被坑高价,这大概是每个准备上线官网或商城的老板最真实的焦虑。别急着骂街,我也被坑过。早期为了省钱,找个小工作室,结果上线三个月,网站打开速度像蜗牛,SEO排名直接掉到…

阅读更多 →
手机网页模板避坑指南:5个维度对比评测教你挑出高转化方案 2026/9/27 5:56:58

手机网页模板避坑指南:5个维度对比评测教你挑出高转化方案

手机网页模板避坑指南:5个维度对比评测教你挑出高转化方案 别再把“模板网站太丑不够用”挂在嘴边了,那是三年前的话。现在你挑的模板,如果首页加载超过2秒,用户手指还没滑完Banner,流量就漏光了。很多老板觉得模板只是换个皮,其实那是自欺欺人…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉