2016-08-23 3 views
1

У меня есть требование, когда я перебираю 10 записей и вставляю эти записи в 3 разные таблицы внутри транзакции. Я беру запись за раз из цикла с транзакцией.Как продолжить после ошибки в блоке 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

Попробуйте что-нибудь вроде ниже. В разделе 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 
    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

Реализовать попытку ... уловить только ваш цикл 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 по мере необходимости. –

Смежные вопросы