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。
我正在学习数据库设计与开发课程,我刚刚了解了 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。