我有一个存储过程,它每天早上在SQL Server 2008 R2中自动运行,此存储过程的一部分涉及执行其他存储过程。因此可以概括格式:
BEGIN TRY
-- Various SQL Commands
EXECUTE storedprocedure1
EXECUTE storedprocedure2
-- etc
END TRY
BEGIN CATCH
--This logs the error to a table
EXECUTE errortrappingprocedure
END CATCH
storedprocedure1和storedprocedure2基本上截断一个表并从另一个表中选择它。有点像:
BEGIN TRY
TRUNCATE Table1
INSERT INTO Table1 (A, B, C)
SELECT A, B, C FROM MainTable
END TRY
BEGIN CATCH
EXECUTE errortrappingprocedure
END CATCH
错误捕获过程包含:
INSERT INTO
[Internal].dbo.Error_Trapping
(
[Error_Number],
[Error_Severity],
[Error_State],
[Error_Procedure],
[Error_Line],
[Error_Message],
[Error_DateTime]
)
(
SELECT
ERROR_NUMBER(),
ERROR_SEVERITY(),
ERROR_STATE(),
ERROR_PROCEDURE(),
ERROR_LINE(),
ERROR_MESSAGE(),
GETDATE()
)
99%的时间可以使用,但偶尔我们会发现storedprocedure1还没有完成,Table1只是部分填充。但是,我们的错误表中没有记录任何错误。我已经测试了错误捕获程序,它确实有效。
当我稍后手动运行storedprocedure1时,它就完成了。此时源表中的数据不会发生变化,因此显然数据不存在问题,在该瞬间发生了导致程序失败的其他事情。有没有更好的方法让我在这里记录错误,或者在数据库中的其他地方我可以试着找出它失败的原因?
答案 0 :(得分:1)
尝试使用SET ARITHABORT
(请参阅link)。在您的情况下,它必须ROLLBACK
。 @Kartic的答案似乎也很合理。
我还建议阅读有关implicit
和explicit
交易的内容 - 我认为这是您的问题。您有几个隐式事务,当发生错误时,您处于工作中间 - 因此只有部分是rollbackеd
并且您在该表中有一些数据。
答案 1 :(得分:0)
有一些类型的错误,TRY..CATCH块无法处理它们,请在此处查看更多信息https://technet.microsoft.com/en-us/library/ms179296(v=sql.105).aspx。对于此类错误,您应该在应用程序中处理它们。 另外我认为您的应用程序中也可能存在事务管理问题。
答案 2 :(得分:0)
我不确定我是否完全了解你。下面的代码太大而无法发表评论。所以张贴作为答案供您参考。如果这不是你想要的,我会删除它。
我们也可以添加交易处理部分。
DECLARE @err_msg NVARCHAR(MAX)
BEGIN TRY
BEGIN TRAN
-- Your code goes here
COMMIT TRAN
END TRY
BEGIN CATCH
SET @err_msg = ERROR_MESSAGE()
SET @err_msg = REPLACE(@err_msg, '''', '''''')
ROLLBACK TRAN
-- Do something with @err_msg
END CATCH