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

MySQL多值子查询执行UPDATE操作时Subquery returns more than 1 row报错的解决方法及循环更新实现问询

解决"Subquery returns more than 1 row"错误并实现批量更新

你遇到的问题很典型:当WHERE子句里用=匹配子查询结果时,子查询返回多行就会触发这个错误。其实不用手动写循环,SQL本身是集合型语言,我们可以用JOIN来一次性处理所有匹配的行,效率比循环高得多。

推荐方案:用JOIN替代子查询

把你的UPDATE语句改成JOIN关联的形式,这样可以同时匹配所有从combo_estoque返回的estoques_id,一次性完成所有更新:

UPDATE estoque_tamanhos tam
JOIN combo_estoque ce ON tam.estoques_id = ce.estoques_id
SET tam.qtde = tam.qtde - IF(NEW.tipo = 'K', NEW.qtde_prod * NEW.qtde_lote, NEW.qtde_prod)
WHERE ce.produtos_id = NEW.produtos_id
AND UPPER(tam.tamanho) = UPPER(NEW.tamanho_prod);

为什么这个方法可行?

  • JOIN会把estoque_tamanhos和combo_estoque中所有匹配estoques_id的行关联起来,相当于自动遍历了子查询返回的所有结果
  • 这种集合操作是数据库优化器最擅长的,性能比手动循环好很多,也不会出现重复处理的问题(因为每一行匹配一次就更新一次)

特殊场景:如果一定要用循环(不推荐)

如果因为业务逻辑限制必须用循环处理每一个estoques_id,可以写一个存储过程来实现:

DELIMITER //
CREATE PROCEDURE update_estoque_tamanhos(IN p_produtos_id INT, IN p_tipo VARCHAR(1), IN p_qtde_prod INT, IN p_qtde_lote INT, IN p_tamanho_prod VARCHAR(20))
BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE v_estoques_id INT;
    -- 声明游标遍历子查询结果
    DECLARE cur CURSOR FOR SELECT estoques_id FROM combo_estoque WHERE produtos_id = p_produtos_id;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    OPEN cur;
    read_loop: LOOP
        FETCH cur INTO v_estoques_id;
        IF done THEN
            LEAVE read_loop;
        END IF;
        -- 执行单条更新
        UPDATE estoque_tamanhos tam
        SET tam.qtde = tam.qtde - IF(p_tipo = 'K', p_qtde_prod * p_qtde_lote, p_qtde_prod)
        WHERE tam.estoques_id = v_estoques_id
        AND UPPER(tam.tamanho) = UPPER(p_tamanho_prod);
    END LOOP;
    CLOSE cur;
END //
DELIMITER ;

然后调用这个存储过程:

CALL update_estoque_tamanhos(NEW.produtos_id, NEW.tipo, NEW.qtde_prod, NEW.qtde_lote, NEW.tamanho_prod);

注意事项

  • 除非万不得已,尽量不要用游标循环,因为数据库的集合操作效率远高于逐行处理
  • 游标循环可能会带来锁表、性能低下的问题,尤其是数据量较大的时候

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 11:19:11