2016-08-23 53 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。 –