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

仅在第一个UPDATE查询成功时执行后续SQL事务查询的实现问题

解决方案:控制事务内SQL查询的执行逻辑

要实现“仅第一个查询影响行数不为0时才执行后续两个查询”的需求,单纯的事务无法自动跳过后续语句,必须结合MySQL的ROW_COUNT()函数和流程控制逻辑来实现。以下是两种可行方案:

方案一:事务内嵌入流程控制(需在存储过程/脚本中执行)

利用ROW_COUNT()获取上一次更新的影响行数,若为0则立即回滚事务并终止操作:

START TRANSACTION;

-- 执行第一个更新
UPDATE history H 
INNER JOIN sku S ON S.skuID = H.skuID 
SET H.endTime = NOW(), 
    H.end_phone_lat = '1', 
    H.end_phone_lng = '2', 
    H.end_lat = S.lat, 
    H.end_lng = S.lng 
WHERE H.skuID = '10' AND S.phone = '12345' 
ORDER BY H.historiID DESC LIMIT 1;

-- 检查第一个更新的影响行数,为0则回滚终止
IF ROW_COUNT() = 0 THEN
    ROLLBACK;
    LEAVE;
END IF;

-- 执行第二个更新
UPDATE sku 
SET phone = NULL, 
    onDrive = 0, 
    lastRideStart = NULL 
WHERE skuID = '10' AND phone = '12345';

-- 执行第三个更新
UPDATE users 
SET kredit = kredit - (
    SELECT ROUND(TIMESTAMPDIFF(SECOND, startTime, endTime)*0.1666666666666667, 0) 
    FROM history 
    WHERE skuID = '10' AND phone = '12345' 
    ORDER BY historiID DESC LIMIT 1
) 
WHERE phone = '12345';

COMMIT;

方案二:封装为存储过程(推荐,更易复用)

将逻辑封装成存储过程,调用时只需传入参数,内部自动处理流程控制:

DELIMITER //

CREATE PROCEDURE ProcessRideCompletion(IN p_skuID VARCHAR(20), IN p_phone VARCHAR(20))
BEGIN
    START TRANSACTION;

    -- 执行第一个更新
    UPDATE history H 
    INNER JOIN sku S ON S.skuID = H.skuID 
    SET H.endTime = NOW(), 
        H.end_phone_lat = '1', 
        H.end_phone_lng = '2', 
        H.end_lat = S.lat, 
        H.end_lng = S.lng 
    WHERE H.skuID = p_skuID AND S.phone = p_phone 
    ORDER BY H.historiID DESC LIMIT 1;

    -- 检查影响行数,为0则回滚并返回提示
    IF ROW_COUNT() = 0 THEN
        ROLLBACK;
        SELECT '第一个更新无匹配行,操作已终止' AS result;
        RETURN;
    END IF;

    -- 执行第二个更新
    UPDATE sku 
    SET phone = NULL, 
        onDrive = 0, 
        lastRideStart = NULL 
    WHERE skuID = p_skuID AND phone = p_phone;

    -- 执行第三个更新
    UPDATE users 
    SET kredit = kredit - (
        SELECT ROUND(TIMESTAMPDIFF(SECOND, startTime, endTime)*0.1666666666666667, 0) 
        FROM history 
        WHERE skuID = p_skuID AND phone = p_phone 
        ORDER BY historiID DESC LIMIT 1
    ) 
    WHERE phone = p_phone;

    COMMIT;
    SELECT '所有操作执行成功' AS result;
END //

DELIMITER ;

调用方式

CALL ProcessRideCompletion('10', '12345');

关键说明

  • ROW_COUNT():返回上一条SQL语句影响的行数,是实现分支逻辑的核心。
  • 普通事务仅保证原子性(要么全执行要么全回滚),但不会自动跳过后续语句,必须通过流程控制主动终止。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 05:10:16