我有一个较大的存储过程,其中利用了几个TRY/CATCH块来捕获和记录单个错误。我还将整个过程的内容包装在事务中,以便在沿途引发错误时能够回滚整个过程(以防止大量混乱的清理);由于否则不会回滚整个事务,因此已启用XACT_ABORT。
关键组件: 我的数据库中有一个表,每次运行此过程时都会插入一条记录,其中包含操作结果和出现问题的详细信息。
有趣的事情正在发生-实际上,当我最终弄清楚出了什么问题时,它非常明显...插入语句到我的日志表也被回滚了,因此,如果我不是在SSMS中运行这个过程,我将无法看到甚至没有运行,因为回滚会删除所有活动痕迹。
问题: 是否可能在除此之外的整个事务回滚时保留此单个插入语句?我仍然希望保留在运行存储过程期间编译的错误消息。
非常感谢!
~ Eli
更新6/28: 以下是我正在查看的代码示例。与@Alex和@gameiswar提出的示例的关键区别在于,在我的情况下,所有try/catch块都嵌套在单个事务中。这样做的目的是有多个catch(针对多个表),尽管最后一个更新失败,我们仍希望整个混乱都被回滚。
关键组件: 我的数据库中有一个表,每次运行此过程时都会插入一条记录,其中包含操作结果和出现问题的详细信息。
有趣的事情正在发生-实际上,当我最终弄清楚出了什么问题时,它非常明显...插入语句到我的日志表也被回滚了,因此,如果我不是在SSMS中运行这个过程,我将无法看到甚至没有运行,因为回滚会删除所有活动痕迹。
问题: 是否可能在除此之外的整个事务回滚时保留此单个插入语句?我仍然希望保留在运行存储过程期间编译的错误消息。
非常感谢!
~ Eli
更新6/28: 以下是我正在查看的代码示例。与@Alex和@gameiswar提出的示例的关键区别在于,在我的情况下,所有try/catch块都嵌套在单个事务中。这样做的目的是有多个catch(针对多个表),尽管最后一个更新失败,我们仍希望整个混乱都被回滚。
SET XACT_ABORT ON;
BEGIN TRANSACTION
DECLARE @message AS VARCHAR(MAX) = '';
-- TABLE 1
BEGIN TRY
UPDATE TABLE xx
SET yy = zz
END TRY
BEGIN CATCH
SET @message = 'TABLE 1 '+ ERROR_MESSAGE();
INSERT INTO LOGTABLE
SELECT
GETDATE(),
@message
RETURN;
END CATCH
-- TABLE 2
BEGIN TRY
UPDATE TABLE sss
SET tt = xyz
END TRY
BEGIN CATCH
SET @message = 'TABLE 2 '+ ERROR_MESSAGE();
INSERT INTO LOGTABLE
SELECT
GETDATE(),
@message
RETURN;
END CATCH
COMMIT TRANSACTION