MySQL 事务语句中的查询错误处理

Query Error Handling in MySQL Transaction Statement

我正在学习数据库设计与开发课程,我刚刚了解了 SQL 事务。教科书(Alan Beaulieu 的学习 SQL 第 3 版)非常擅长解释事物的工作原理,但不太擅长给出我们需要使用的实际代码的示例。

教科书中,几乎唯一谈到事务中错误处理的地方,就是一个事务语句的例子,但它只是伪代码:

START TRANSACTION;

/* withdraw money from first account, making sure balance is sufficient */
UPDATE account SET avail_balance = avail_balance - 500
WHERE account_id = 9988
  AND avail_balance > 500;

IF <exactly one row was updated by the previous statement> THEN
  /* deposit money into second account */
  UPDATE account SET avail_balance = avail_balance + 500
    WHERE account_id = 9989;

  IF <exactly one row was updated by the previous statement> THEN
    /* everything worked, make the changes permanent */
    COMMIT;
  ELSE
    /* something went wrong, undo all changes in this transaction */
    ROLLBACK;
  END IF;
ELSE
  /* insufficient funds, or error encountered during update */
  ROLLBACK;
END IF;

在 MySQL workbench(我们用来测试查询的软件)中,我尝试使用 CASE 语句而不是 IF(因为 MySQL 使用 CASE 而不是 IF),但它会给我一个错误:

"CASE" is not valid at this position, expecting EOF, ALTER...

我试着查找如何做到这一点,但我发现的所有内容要么不适用于 MySQL(Oracle 数据库或 Microsoft SQL 服务器),要么与(没有)一样有用教科书是...

如有任何帮助,我们将不胜感激!

您控制流程的方式将取决于客户端,这就是为什么您的教科书示例是伪代码的原因。我认为在 MySQL Workbench 的查询选项卡中的 SQL 脚本中没有任何方法可以控制流程,但我可能错了。

您当然可以创建一个存储过程来封装原始 post -

中列出的示例事务
CREATE PROCEDURE `sp_TransferFunds`(
    IN amount DECIMAL(12,2),
    IN sendingAccount INTEGER,
    IN receivingAccount INTEGER
)
sp:BEGIN
    /* do some validation of the input parameters */
    IF amount <= 0 THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Amount to be transferred must be greater than zero';
        LEAVE sp;
    ELSEIF sendingAccount = receivingAccount THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Sending and receiving accounts must be different';
        LEAVE sp;
    END IF;

    START TRANSACTION;

    /* withdraw money from first account, making sure balance is sufficient */
    UPDATE account
        SET avail_balance = avail_balance - amount
    WHERE account_id = sendingAccount
    AND avail_balance >= amount;

    SET @tx1 = ROW_COUNT();

    IF (@tx1 = 1) THEN
        /* deposit money into second account */
        UPDATE account
            SET avail_balance = avail_balance + amount
        WHERE account_id = receivingAccount;

        SET @tx2 = ROW_COUNT();
    
        IF (@tx2 = 1) THEN
            /* everything worked, make the changes permanent */
            COMMIT;
        ELSE
            /* something went wrong, undo all changes in this transaction */
            ROLLBACK;
            SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Something went wrong!';
        END IF;
    ELSE
        /* insufficient funds, or error encountered during update */
        ROLLBACK;
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Insufficient funds in sendingAccount!';
    END IF;
END

如果这没有帮助并且您有更具体的示例来说明您要实现的目标,请更新您的原始 post。