MySQL递归存储过程遇SQL语句失效,求排查BOM树存储过程问题
排查递归BOM存储过程的游标问题
让我们一步步拆解你遇到的问题:你的Disptree递归存储过程在移除CR_SQL5的游标操作后能正常展示BOM层级,但保留这三行代码就无法正常运行。结合你提供的表结构和代码,核心问题大概率出在全局的NOT FOUND处理器被意外触发后,中断了主循环,下面是具体分析和修复方案:
1. 核心问题:DONE标志被游标操作篡改
你声明了一个全局的CONTINUE HANDLER FOR NOT FOUND SET DONE:=TRUE;,这个处理器会在任何游标执行FETCH但没有返回数据时触发,将DONE设为TRUE。
当CR_SQL5查询MRP表时,如果没有找到匹配CPRODUCTID和CALWEEK的记录,DONE会被设为TRUE。接下来回到主循环LP_LOP1时,IF DONE THEN LEAVE LP_LOP1; END IF;会直接退出循环,导致后续的物料节点无法被递归处理,整个BOM树的遍历就中断了。
2. 修复方案:重置DONE标志再操作游标
在每次打开CR_SQL5之前,手动把DONE重置为FALSE,避免之前的游标操作影响主循环。修改后的代码片段如下:
-- ... 之前的代码 ... select CAL_REQDATE,CPRODUCTID,CALWEEK; -- 重置DONE标志,避免CR_SQL5无数据时篡改全局状态 SET DONE := FALSE; OPEN CR_SQL5; FETCH CR_SQL5 INTO MRP_ID; CLOSE CR_SQL5; CALL disptree(CPRODUCTID,REQQTY,REQDATE,PRODUCTID); -- ... 后续代码 ...
3. 额外验证点
- 你可以单独测试
CR_SQL5的查询逻辑,比如执行SELECT MRP.MRPID FROM MRP WHERE MRP.PRODUCTID='某个测试ID' AND MRP.SCH_WEEK='对应周数';,确认是否存在无数据的场景——这是触发问题的直接诱因,但只要重置DONE就不会影响主流程。 - 检查
CALWEEK是否可能为0(比如REQDATE为空时),如果MRP表的schweek字段没有0值,这种情况一定会触发NOT FOUND处理器,更需要重置DONE。
内容的提问来源于stack exchange,提问作者Kash
相关产品推荐
相关产品推荐

