MySQL存储过程游标报Error Code:1329无数据行获取问题
报错核心原因
触发Error Code: 1329 No data rows fetched ,selected or processed的直接原因是存储过程缺少游标遍历结束的异常处理逻辑,结合需求原代码共有4处问题:
- 未声明
NOT FOUND条件的处理程序:游标遍历到最后一行、无更多数据可拉取时,FETCH操作会直接抛出1329异常;原代码中is_done变量始终为默认值0,永远不会触发leave getdata的循环退出逻辑,循环会无限执行直到FETCH取数失败抛错。 - 游标未做部门筛选:原游标查询全量员工表数据,没有过滤HR部门员工,不符合需求。
- 缺少需求指定的
emp_names变量:原代码只定义了存储单个员工全名的full_name变量,每次循环都会覆盖上一次的赋值,无法存储所有HR员工的全名。 - 无结果拼接逻辑:原代码没有把单个员工的全名聚合到目标变量的逻辑,无法实现需求。
修正方案
调整后的可正常运行的存储过程代码如下:
CREATE DEFINER=`root`@`localhost` PROCEDURE `new_procedure`() BEGIN declare emp_id int; declare first_name varchar(30); declare last_name varchar(30); declare full_name varchar(60); -- 新增需求要求的聚合变量,根据HR部门员工总人数调整字符长度即可 declare emp_names varchar(2000) default ''; declare is_done int default 0; -- 调整游标:增加HR部门筛选条件,若部门数据存在关联部门表,可改为join关联后筛选 declare emp_c cursor for select emp_id, First_name,last_name from employee where department = 'HR'; -- 替换为你实际表中标识HR部门的判断条件 -- 补充缺失的游标结束异常处理:无数据可取时自动将结束标记设为1 declare continue handler for not found set is_done = 1; open emp_c; getdata:loop fetch next from emp_c into emp_id,first_name,last_name; if is_done =1 then leave getdata; end if; set full_name = concat(first_name," ",last_name); -- 逐次拼接员工全名到目标变量,用逗号做分隔符,可根据需求替换分隔符 set emp_names = concat(emp_names, if(emp_names = '', '', ', '), full_name); end loop; close emp_c; -- 此处可根据业务需求使用emp_names变量,示例为直接返回聚合结果 select emp_names as hr_employee_names; END
关键调整点说明:
- 补充
declare continue handler for not found set is_done = 1;逻辑,游标取数到末尾时自动标记循环结束,不会触发1329报错。 - 游标查询增加HR部门过滤条件,只拉取需要处理的员工数据。
- 新增
emp_names变量作为聚合存储的目标变量,初始值设为空字符串,避免拼接时空值导致整个结果为NULL。 - 循环内增加拼接逻辑,每取到一个有效员工的姓名,就追加到
emp_names变量中,不会覆盖之前的结果。 - 保留「先FETCH、再判断是否结束、最后处理数据」的顺序,避免最后一次无数据时把空值拼入结果。
内容的提问来源于stack exchange,提问作者Sri Vishnu
相关产品推荐
相关产品推荐

