关于此 SQL 语句的 ROLLBACK TRANSACTION 的任何想法

发布于 2024-12-16 01:28:05 字数 695 浏览 3 评论 0原文

有人可以帮我解决这个 SQL 语句吗?我在 SQL Server 引擎上运行它。

我有以下语句,删除表中的所有条目并用新条目替换它们:

SET XACT_ABORT ON;
BEGIN TRANSACTION;
DELETE FROM [t1] WHERE [id]>10;
INSERT INTO [t1] ([id], [v2], [v3]) SELECT COALESCE(MAX([id]), 0)+1, 'a1', 'b1' FROM [t1];
INSERT INTO [t1] ([id], [v2], [v3]) SELECT COALESCE(MAX([id]), 0)+1, 'a2', 'b2' FROM [t1];
--and so on, I may have up to 100 of these inserts
INSERT INTO [t1] ([id], [v2], [v3]) SELECT COALESCE(MAX([id]), 0)+1, 'aN', 'bN' FROM [t1];
COMMIT;
SET XACT_ABORT OFF;

我想知道的是,如果上述事务失败,如何使用 ROLLBACK?

附言。我基本上需要将数据库恢复到以前的状态,以防上述语句中出现任何错误。

编辑: 使用 SET XACT_ABORT ON 进行更新;下面建议的声明。这是它应该看起来的样子吗?

Can someone help me with this SQL statement. I run it on the SQL Server engine.

I have the following statement that removes all entries in the table and replaces them with new ones:

SET XACT_ABORT ON;
BEGIN TRANSACTION;
DELETE FROM [t1] WHERE [id]>10;
INSERT INTO [t1] ([id], [v2], [v3]) SELECT COALESCE(MAX([id]), 0)+1, 'a1', 'b1' FROM [t1];
INSERT INTO [t1] ([id], [v2], [v3]) SELECT COALESCE(MAX([id]), 0)+1, 'a2', 'b2' FROM [t1];
--and so on, I may have up to 100 of these inserts
INSERT INTO [t1] ([id], [v2], [v3]) SELECT COALESCE(MAX([id]), 0)+1, 'aN', 'bN' FROM [t1];
COMMIT;
SET XACT_ABORT OFF;

What I want to know is how do you use ROLLBACK in case the transaction above fails?

PS. I basically need to revert the database to what it used to be in case of any error in that statement above.

EDIT:
Updated with the SET XACT_ABORT ON; statement suggested below. Is it how it's supposed to look?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

昔梦 2024-12-23 01:28:05

如果您希望事务在发生错误时完全回滚,则需要设置SET XACT_ABORT ON

将其设置为ON后,如果任何语句失败,事务将回滚。您不需要调用 ROLLBACK 来实现这一点。

在这种情况下,当您使用 BEGIN TRANSACTION 时,每个语句都将成为该事务的一部分,这意味着它们要么全部工作,要么全部失败。如果在COMMIT之前出现错误,事务将回滚,并且您的数据库将处于与BEGIN TRANSACTION之前相同的状态(假设没有其他客户端正在更改事务)同时数据库)。

请参阅 XACT_ABORT 的文档。

You need to set SET XACT_ABORT ON if you want the transaction to fully rollback on an error.

With this set to ON, if any of the statements fails, the transaction will rollback. You do not need to call ROLLBACK for that to happen.

Under this condition, the moment you use a BEGIN TRANSACTION, every statement will be part of that transaction, meaning they will all either work or all fail. If there is an error before the COMMIT, the transaction will rollback and you database will be at the same state it was as before BEGIN TRANSACTION (assuming no other clients are changing the database at the same time).

See the documentation for XACT_ABORT.

深居我梦 2024-12-23 01:28:05

@Oded 介绍了一种自动处理回滚的好方法。为了完整起见,我将为您提供另一种方法来显式处理这种情况,使用 try catch< /a>.

BEGIN TRANSACTION;

BEGIN TRY
    DELETE FROM [t1] WHERE [id]>10;
    INSERT INTO [t1] ([id], [v2], [v3]) SELECT COALESCE(MAX([id]), 0)+1, 'a1', 'b1' FROM [t1];
    INSERT INTO [t1] ([id], [v2], [v3]) SELECT COALESCE(MAX([id]), 0)+1, 'a2', 'b2' FROM [t1];
    --and so on, I may have up to 100 of these inserts
    INSERT INTO [t1] ([id], [v2], [v3]) SELECT COALESCE(MAX([id]), 0)+1, 'aN', 'bN' FROM [t1];
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION;
END CATCH;

IF @@TRANCOUNT > 0
    COMMIT TRANSACTION;
GO

@Oded has covered an good approach to handle your rollback automatically. For completeness, I'll give you another method to handle that situation explicitly using try catch.

BEGIN TRANSACTION;

BEGIN TRY
    DELETE FROM [t1] WHERE [id]>10;
    INSERT INTO [t1] ([id], [v2], [v3]) SELECT COALESCE(MAX([id]), 0)+1, 'a1', 'b1' FROM [t1];
    INSERT INTO [t1] ([id], [v2], [v3]) SELECT COALESCE(MAX([id]), 0)+1, 'a2', 'b2' FROM [t1];
    --and so on, I may have up to 100 of these inserts
    INSERT INTO [t1] ([id], [v2], [v3]) SELECT COALESCE(MAX([id]), 0)+1, 'aN', 'bN' FROM [t1];
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION;
END CATCH;

IF @@TRANCOUNT > 0
    COMMIT TRANSACTION;
GO
雨落□心尘 2024-12-23 01:28:05

您没有提到您的 SQL Server 版本 - 但从 2005 版本开始,您可以使用 BEGIN TRY... END TRY BEGIN CATCH... END CATCH 样式异常处理。

我通常将语句块包装在事务/try-catch 块骨架中,如下所示:

BEGIN TRANSACTION
BEGIN TRY

    -- put your statements to be executed *HERE*    

    COMMIT TRANSACTION
END TRY
BEGIN CATCH
    SELECT 
        ERROR_NUMBER() AS ErrorNumber,
        ERROR_SEVERITY() AS ErrorSeverity,
        ERROR_STATE() AS ErrorState,
        ERROR_PROCEDURE() AS ErrorProcedure,
        ERROR_LINE() AS ErrorLine,
        ERROR_MESSAGE() AS ErrorMessage

    ROLLBACK TRANSACTION
END CATCH

该块尝试执行我的语句 - 如果成功,则提交事务,如果发生异常,则执行跳转到 CATCH 块,打印出详细的错误信息,并回滚交易

You didn't mention your version of SQL Server - but starting with the 2005 version, you can use BEGIN TRY... END TRY BEGIN CATCH... END CATCH style exception handling.

I typically wrap my statement blocks in a transaction/try-catch block skeleton something like this:

BEGIN TRANSACTION
BEGIN TRY

    -- put your statements to be executed *HERE*    

    COMMIT TRANSACTION
END TRY
BEGIN CATCH
    SELECT 
        ERROR_NUMBER() AS ErrorNumber,
        ERROR_SEVERITY() AS ErrorSeverity,
        ERROR_STATE() AS ErrorState,
        ERROR_PROCEDURE() AS ErrorProcedure,
        ERROR_LINE() AS ErrorLine,
        ERROR_MESSAGE() AS ErrorMessage

    ROLLBACK TRANSACTION
END CATCH

That block tries to execute my statements - if it succeeds, the transaction is committed, if an exception happens, the execution jumps into the CATCH block, prints out detailed error info, and rolls back the transaction

水水月牙 2024-12-23 01:28:05

您可以尝试以下方法:

BEGIN TRY
   BEGIN TRANSACTION 
     DELETE FROM tablename WHERE id>1
     --- set of your querys 
    COMMIT
END TRY

BEGIN CATCH 
    IF @@TRANCOUNT > 0  
       ROLLBACK 
END CATCH

You can try the following method:

BEGIN TRY
   BEGIN TRANSACTION 
     DELETE FROM tablename WHERE id>1
     --- set of your querys 
    COMMIT
END TRY

BEGIN CATCH 
    IF @@TRANCOUNT > 0  
       ROLLBACK 
END CATCH
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文