You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL执行包含循环的存储过程时提示Query was empty错误

错误成因
  • 子查询返回空集触发报错:当A_Request表中不存在id = incr的记录,或是当前incr对应的bId在B_ProductLine表中没有匹配记录时,UPDATE语句里的赋值子查询会返回空结果,触发MySQL的Query was empty报错。你单独测试SQL时一般指定了实际存在的id值,没有覆盖到缺数场景,因此不会触发报错。
  • 嵌套子查询的作用域歧义:原代码中多层嵌套引用A_Request表,存储过程运行时可能出现表别名优先级混淆,导致部分场景下匹配不到记录,返回空查询。
  • 循环逻辑未做断号兼容:如果A_Request的id不是从1到76连续分布,遇到断号的incr值时,UPDATE语句完全没有匹配行,直接触发空查询报错。
解决办法

修改后的完整存储过程如下:

DELIMITER $$
CREATE PROCEDURE updateA()
BEGIN
DECLARE incr INT DEFAULT 1;
DECLARE current_bId INT;
a_loop: LOOP
    -- 先校验当前id对应的记录是否存在
    SELECT bId INTO current_bId FROM `A_Request` WHERE `id` = incr LIMIT 1;
    -- 不存在则直接跳过本轮循环
    IF current_bId IS NULL THEN
        SET incr = incr + 1;
        IF incr = 77 THEN
            LEAVE a_loop;
        END IF;
        ITERATE a_loop;
    END IF;
    -- 执行更新,简化子查询消除歧义
    UPDATE `A_Request` SET `requestRegion` = 
    (SELECT
    GROUP_CONCAT( DISTINCT
    (CASE
    WHEN subRegion in (4,5) THEN 108
    WHEN subRegion in (6,7) THEN 109
    WHEN subRegion in (195,201) THEN 111
    ELSE null
    END) SEPARATOR '; '
    )
    as `newRegion`
    FROM `B_ProductLine` where requestId = current_bId group by requestId) 
    WHERE `id` = incr;

    SET incr = incr + 1;
    IF incr = 77 THEN
        LEAVE a_loop;
    END IF;
END LOOP a_loop;
END $$;
DELIMITER ;

主要修改点:

  • 新增记录存在性校验逻辑,不存在对应记录时直接跳过本轮循环,从根源避免空查询报错。
  • 提取bId为单独变量,简化嵌套子查询,消除表引用的作用域歧义。
  • 如果业务需要空值场景下requestRegion赋值为默认值,可以在GROUP_CONCAT外层套IFNULL()函数实现。

内容的提问来源于stack exchange,提问作者seph1119

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 02:33:01