首页/新闻资讯/正文详情

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

发布时间:2026/9/26 4:08:33 来源:云帆数科 栏目:资讯中心
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 批量少用逐行游标逻辑。 返回目录

相关推荐

小白程序员如何守住核心竞争力,拥抱AI新机遇(收藏版)
小白程序员如何守住核心竞争力,拥抱AI新机遇(收藏版)

面对大模型的快速发展,我们无需过度焦虑被替代。人类独有的情感与创造力是不可替代的核心竞争力。同时,积极拥抱AI,如成为AI应用开发工程师或大模型训练师,这些新兴岗位对编程要求不高,更看重行业理解和耐心&#xff0… · 2026/9/26 4:08:15

Harness工程:新手程序员轻松掌握大模型运行环境,收藏必备!
Harness工程:新手程序员轻松掌握大模型运行环境,收藏必备!

Harness工程是Agent的运行环境,负责工具权限、任务状态、检查、运行轨迹和预算,而非模型本身。通过优化外围配置,可显著提升大模型体验。文章以Claude Code为例,说明模型未变时,配置调整导致体验差异。重点介绍Harness… · 2026/9/26 4:08:15

拓客工具计费模式选型:按条付费与包年的成本测算方法
拓客工具计费模式选型:按条付费与包年的成本测算方法

拓客工具的计费模式选型,核心逻辑是先估算清楚自己的月均使用量。按条付费和包年付费,分别适合什么样的使用场景?按条付费更适合用量不确定、需求偏零散的场景,比如刚开始尝试企业获客软件,还没摸清楚自己每个月到底要… · 2026/9/26 4:08:15

虚拟机死循环重启排查与修复全攻略
虚拟机死循环重启排查与修复全攻略

相信每一个玩虚拟机的朋友都经历过那种令人抓狂的时刻:虚拟机一开机,还没进入桌面,就自动重启,反复循环,像中了邪一样。尤其是当你手头有重要工作,或者刚配好一个复杂的开发环境还没来得及快照的时候&#… · 2026/9/26 4:45:57

Unity 2D弹幕射击游戏复现指南:从基础移动到对象池优化实践
Unity 2D弹幕射击游戏复现指南:从基础移动到对象池优化实践

简介:面向Unity 2D开发者的“雷霆战机”演示工程资源,适合刚入门游戏开发的学生或独立开发者学习弹幕射击玩法的完整实现。压缩包内共1740个文件,以DLL插件、Unity场景与脚本、材质球(mat)、预设体(prefab&… · 2026/9/26 4:45:57

rn_for_openharmony 列表组件实战:FlatList 鸿蒙化适配与性能调优
rn_for_openharmony 列表组件实战:FlatList 鸿蒙化适配与性能调优

先说结论:如果你所在的团队正在做 OpenHarmony 应用适配,又不想把 React Native 那套現有业务代码推翻重写,那 rn_for_openharmony 基本就是绕不开的方案。而这个方案里,你最频繁打交道的组件一定是列表。首页列表、消息列表、设置… · 2026/9/26 4:45:57

Flutter鸿蒙漫画阅读器开发实战:环境搭建、图片缓存与性能优化
Flutter鸿蒙漫画阅读器开发实战:环境搭建、图片缓存与性能优化

第一次把Flutter项目往鸿蒙上跑的时候,我以为只要装上DevEco Studio、配好SDK,剩下就是点一下Run的事。结果编译报错一个接一个,cached_network_image在鸿蒙上直接不可用,图片缓存目录拿到的路径和Android完全不是一个套路&#x… · 2026/9/26 4:45:57

STVP烧录工具详解:STM8固件烧录、ST-Link接线与命令行批量操作
STVP烧录工具详解:STM8固件烧录、ST-Link接线与命令行批量操作

简介:STVP烧录工具(ST Visual Programmer)是ST官方推出的嵌入式烧录软件,面向使用ST-LINK调试器的STM8/STM32开发者,解决固件下载与配置难题。压缩包共197个文件,约6.14MB,以s19固件镜像、dll动… · 2026/9/26 4:45:57

Rancher多集群管理实战:部署、权限与运维排错全解析
Rancher多集群管理实战:部署、权限与运维排错全解析

1. Rancher到底解决了什么问题:多套K8s的混乱是真实痛点先说个很多人都有过的场景:公司里两三个核心集群,再加上测试、预发,一共五六套Kubernetes环境。每套环境一个kubeconfig文件,为了区分还得改一个很长的context名… · 2026/9/26 4:45:51

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21

OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40

向下兼容与向上兼容:接口设计中的兼容性策略与工程实践
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践

一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码