2016-08-23 20 views
1

我有一个要求,我要循环10条记录,并将这些记录插入到事务中的3个不同的表中。我从while循环与交易中一次一个记录。如何在catch块中出错后继续?

我的要求是,如果前8个记录被成功插入,并且如果语句在第9条记录失败,它应该记录错误并继续插入第10条记录。

存储过程不应该停止,如果任何行有任何错误。

我曾尝试将事务放入子TRY-CATCH块但仍失败。

BEGIN TRY 

DECLARE @TotalRecord   AS INT = 10 
     ,@LoopStartCount  AS INT = 1 
     ,@AskPkQuotationId  AS INT;  

--Some select stuff here  
WHILE(@LoopStartCount <= @TotalRecord) 
BEGIN 

    BEGIN TRY 
    BEGIN TRAN 

    --Do some insert update for each record. 

    COMMIT TRAN 
    END TRY 

    BEGIN CATCH 

    --Log Error and Continue with next record 

    END CATCH 
    SET @LoopStartCount = @LoopStartCount + 1; 
    END 



END TRY 
BEGIN CATCH 
--Log parent error 
END CATCH 
+0

所以循环不应该停止错误比为什么你需要一个事务? – GuidoG

+0

@GuidoG如果所选记录引发任何错误,应该回滚该插入并继续下一条记录。 –

+0

但如果所选记录在插入时引发错误,则不会插入,因此不需要回滚?或者我错过了什么? – GuidoG

回答

0

尝试下面的内容。在捕捉部分你可以处理场景。

BEGIN TRY 

DECLARE @TotalRecord   AS INT = 10 
     ,@LoopStartCount  AS INT = 1 
     ,@AskPkQuotationId  AS INT;  

--Some select stuff here  
WHILE(@LoopStartCount <= @TotalRecord) 
BEGIN 

    BEGIN TRY 
    BEGIN TRAN 

    --Do some insert update for each record. 

    COMMIT TRAN 
    END TRY 

    BEGIN CATCH 

    --Log Error and Continue with next record 
    IF @@TRANCOUNT >1 

    BEGIN 
    INSERT INTO dbo.ERROR_DETAILS --INSERTING ErrorInfo INTO LOG TABLE 
    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 TRAN 

    END 
    GOTO LOOPCOUNTER1 
    END CATCH 
    LOOPCOUNTER1: 
    SET @LoopStartCount = @LoopStartCount + 1; 
    END 
END 

END TRY 
BEGIN CATCH 
--Log parent error 
END CATCH 
+0

我应该在catch块中回滚事务,并且此方法不起作用。 –

+0

您可以在catch块本身添加回滚。尝试更新的脚本 –

1

实现try ...只捕获到您的While循环,而不是您的整个代码。我给你在这里的示例演示。

DECLARE @I INT = 0 
DECLARE @Table TABLE (
    ID INT identity(1, 1) 
    ,c2 INT 
    ) 

INSERT INTO @table (c2) 
VALUES (1) 
    ,(2) 
    ,(0) 
    ,(3) 
    ,(4) 

SELECT * 
FROM @Table 

WHILE @I < 5 
BEGIN 
    BEGIN TRY 
     SET @I = @I + 1 

     SELECT @I/(
       SELECT c2 
       FROM @table 
       WHERE ID = @I 
       ) AS Quotient 
    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; 
    END CATCH 
END 

该代码在第三行返回错误,但仍然继续处理直到结束。

+0

如果try块外的代码失败会怎么样? –

+0

在上面的例子中,TRY之外的代码只是为测试设置的。基本结构是正确的。你把你的功能代码放在一个TRY中,你有一个CATCH来处理它。您可以确定CATCH内的计数值以根据需要设置ROLLBACK。 –