2016-08-23 3 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 

このコードは3行目でエラーを返しますが、最後まで処理を続けます。

+0

tryブロックの外側にあるコードが失敗するとどうなりますか? –

+0

上記の例では、TRY以外のコードがテスト用に設定されています。基本的な構造は正しいです。機能コードをTRYの中に入れ、それを処理するためのCATCHがあります。 CATCH内のカウント値を決定して、必要に応じてROLLBACKを設定することができます。 –

関連する問題