MySQL事务语句错误处理:伪代码转可运行代码实现求助
MySQL 事务错误处理可行实现方案
报错原因说明
你遇到的报错:
"CASE" is not valid at this position, expecting EOF, ALTER...
根因为:IF、CASE等流程控制语句属于MySQL存储程序(存储过程、函数、触发器、事件)的专属语法,不能直接在普通SQL查询上下文执行。且MySQL原生支持IF语句,无需用CASE替换。
方案1:存储过程实现(完全匹配教材伪代码逻辑)
该方案最贴合教材的伪代码逻辑,封装后可直接调用执行:
-- 先修改语句分隔符,避免存储过程内部的;被提前解析 DELIMITER // CREATE PROCEDURE sp_account_transfer() BEGIN -- 开启事务 START TRANSACTION; -- 从第一个账户扣款,校验余额充足 UPDATE account SET avail_balance = avail_balance - 500 WHERE account_id = 9988 AND avail_balance > 500; -- 判断是否恰好1行被更新,对应伪代码的IF条件 IF ROW_COUNT() = 1 THEN -- 向第二个账户存款 UPDATE account SET avail_balance = avail_balance + 500 WHERE account_id = 9989; IF ROW_COUNT() = 1 THEN -- 两次更新都成功,提交事务 COMMIT; SELECT '转账成功' AS result; ELSE -- 存款失败,回滚全部修改 ROLLBACK; SELECT '目标账户不存在,转账失败' AS result; END IF; ELSE -- 扣款失败(余额不足/账户不存在),回滚 ROLLBACK; SELECT '扣款账户不存在或余额不足,转账失败' AS result; END IF; END // -- 改回默认分隔符 DELIMITER ; -- 调用存储过程执行转账 CALL sp_account_transfer(); -- 不需要该存储过程时可删除 -- DROP PROCEDURE IF EXISTS sp_account_transfer;
其中ROW_COUNT()是MySQL内置函数,返回上一条DML语句影响的行数,刚好对应伪代码中判断更新行数的需求。
方案2:非存储过程脚本实现(适合临时测试)
如果不想创建存储过程,可直接在Workbench查询窗口分步执行,手动判断结果:
-- 第一步:开启事务,执行扣款 START TRANSACTION; UPDATE account SET avail_balance = avail_balance - 500 WHERE account_id = 9988 AND avail_balance > 500; -- 第二步:查看扣款影响行数 SELECT ROW_COUNT() AS withdraw_affected_rows; -- 如果返回结果为1,继续执行下方存款语句,否则直接执行ROLLBACK -- 第三步:执行存款 UPDATE account SET avail_balance = avail_balance + 500 WHERE account_id = 9989; -- 第四步:查看存款影响行数 SELECT ROW_COUNT() AS deposit_affected_rows; -- 如果返回结果为1,执行COMMIT,否则执行ROLLBACK -- 二选一执行 -- COMMIT; -- ROLLBACK;
内容的提问来源于stack exchange,提问作者Jacob Hornbeck
相关产品推荐
相关产品推荐

