2009-02-16 122 views
3

我想对生产数据库运行更新查询,并且想尽可能保证安全。我期待做以下事情在MySQL中是否存在SQL Server的@@错误的等效项

BEGIN TRANSACTION 
    UPDATE table_x SET col_y = 'some_value' 
    . 
    . 
    . 
IF (@@error <> 0) 
BEGIN 
    ROLLBACK 
END 
ELSE 
BEGIN 
    COMMIT 
END 

上面应该在SQL Server中工作,但我需要这个工作对MySQL数据库。编辑: 对不起,有超过1条语句可以执行。是的,我知道不需要在事务中包装单个查询。

回答

0

我不认为这是必要的,因为存在隐式提交/回滚的概念。

MySQL docs

默认情况下,MySQL的启动会话 与 自动提交模式下启用每个新的连接,因此MySQL确实 如果 该声明没有返回一个 每个SQL语句之后提交错误。如果语句返回 错误,则提交或回滚行为 取决于错误。见 13.6.13,“InnoDB错误处理”。

+0

尽管ROLLBACK还会回滚任何外部嵌套事务(至少在MSSQL中)。我认为OP是在MSSQL中相当于@@ ERROR的MySQL检测方法之后的,这可能只是一个Noddy示例 – Kristen 2009-02-16 09:08:20

+1

我将解释Assaf的说法:作为MSSQL开发人员,将MySQL视为具有SET XACT_ABORT默认开启。直到最近我还不熟悉这个设置。看看这个网站: http://doc.ddart.net/mssql/sql70/set-set_40.htm – DJTripleThreat 2009-06-13 06:16:17

+0

对于任何需要它的人来说,文档已经移到这里https://dev.mysql.com/doc/ refman/5.7/en/innodb-error-handling.html – 2017-07-07 15:04:48

0
BEGIN; 
UPDATE foo SET bar = 3; 
UPDATE bar SET thing = 5; 
COMMIT; 

如果发生错误,则整个事务将被自动回滚。如果应用程序中的某些内容指示需要回滚,则只需执行ROLLBACK即可。


有可能在MySQL中的过程或复合语句中显式处理错误,但我不会推荐沿着这条路线走。请参阅how-to articledocs for DECLARE HANDLER。您还需要find the specific error code you want to handle,或者您可以使用一般的SQLEXCEPTION条件。您还需要查看compound statementsdefining stored programs

无论如何,基于文档,你可以做类似于下面的查询,但它实际上不会做任何不同于我上面的回答。它也会让你非常奇怪看起来使用MySQL的任何人(包括我自己)。

BEGIN 
    DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK; 
    START TRANSACTION; 
    UPDATE foo SET bar = 3; 
    UPDATE bar SET thing = 5; 
    COMMIT; 
END; 

老答案:

如果你执行一个查询,这是没有意义的。只需执行查询;如果发生错误,则不会发生任何事情 - 您的交易将自动回滚。

原因是,默认情况下,所有单个查询都被封装在一个名为“autocommit”模式的“隐藏”事务中。典型的选择是明确使用交易 - 一旦你执行“BEGIN”,你已经开始交易。一旦你COMMIT或ROLLBACK你会回到自动提交模式。

因此,在MySQL中使用事务的唯一原因是如果您希望在发生错误(或其他外部事件)时回滚到特定状态。在MySQL中,如果发生错误,事务总是被中止。

最后,可以完全关闭此行为,然后您必须始终显式使用事务。我相信“BEGIN”隐含于您上次提交或回滚时,但您必须COMMIT或ROLLBACK您运行的任何查询。请参阅The InnoDB Transaction Model以获取更多信息。

1
CREATE PROCEDURE prc_test() 
BEGIN 
    DECLARE EXIT HANDLER FOR SQLEXCEPTION 
    BEGIN 
    ROLLBACK; 
    END; 
    START TRANSACTION; 
    INSERT 
    INTO t_test VALUES ('test', 'test'); 
    INSERT 
    INTO no_such_table 
    VALUES ('no'); 
    COMMIT; 
END; 

CALL prc_test(); 

SELECT * 
FROM t_test; 

0 rows fetched. 
相关问题