有人可以帮我解决这个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?
PS。我基本上需要将数据库恢复到以前在上述语句中出现任何错误时的情况。
修改 更新了SET XACT_ABORT ON;声明如下。是它应该看起来怎么样?
答案 0 :(得分:4)
如果您希望事务完全回滚错误,则需要设置SET XACT_ABORT ON
。
将此设置为ON
,如果任何语句失败,则事务将回滚。您无需致电ROLLBACK
即可。
在这种情况下,当您使用BEGIN TRANSACTION
时,每个语句都将成为该事务的一部分,这意味着它们将全部运行或全部失败。如果在COMMIT
之前发生错误,则事务将回滚,并且您的数据库将处于与BEGIN TRANSACTION
之前相同的状态(假设没有其他客户端同时更改数据库)。
请参阅XACT_ABORT
的文档。
答案 1 :(得分:4)
@Oded已经介绍了一种自动处理回滚的好方法。为了完整起见,我将为您提供另一种方法来使用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
答案 2 :(得分:1)
答案 3 :(得分:1)
您没有提及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
块,打印出详细的错误信息,并回滚事务
答案 4 :(得分:0)
您可以尝试以下方法:
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