2

У меня есть хранимая процедура, которая запускается автоматически каждое утро в SQL Server 2008 R2, часть этой хранимой процедуры включает выполнение других хранимых процедур. Формат может быть суммированы следующим образом:Обработка хранимых процедур SQL Server

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

Вы используете основную хранимую процедуру из задания агента SQL или из приложения/службы? – CrApHeR

+0

Основная хранимая процедура вызывается из внешнего приложения. – fourdam

+0

У вас есть какой-то журнал во внешнем приложении, чтобы проверить, есть ли какое-то исключение или что-то еще? Существует ли вероятность того, что одна из хранимых процедур заблокирована любой другой транзакцией? – CrApHeR

ответ

0

Есть некоторые ошибки, которые TRY..CATCH блок не будет обрабатывать, посмотрите здесь дополнительную информацию https://technet.microsoft.com/en-us/library/ms179296(v=sql.105).aspx. для таких ошибок вы должны обращаться с ними в своем приложении. также я думаю, что у вас может быть проблема с управлением транзакциями в вашем приложении.

+0

Я думаю, что это наиболее вероятная причина, поскольку я тестировал блоки TRY CATCH как в родительской процедуре, так и в дочерних, и они действительно работают. К сожалению, это трудная задача для тестирования и дать окончательный ответ, поскольку я не могу вручную восстановить ошибку. – fourdam

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 
+0

Не уверен, что я очень хорошо себя зарекомендовал, чтобы быть честным!Проблема не в том, действительно ли транзакции откатываются в случае сбоя, так как независимо от того, что мне нужно будет повторно запустить процедуру вручную, которая будет усекать данные из существующей таблицы перед повторным заполнением. Проблема в том, что я не могу точно определить, что на самом деле заставляет процедуру терпеть неудачу в первую очередь. – fourdam

0

Попробуйте использовать SET ARITHABORT (см link). Он должен ROLLBACK в вашем случае. Также ответ @ Kartic кажется разумным.

Я также рекомендовал прочитать о implicit и explicit транзакции - я думаю, что это ваша проблема. У вас несколько неявных транзакций, и когда произошла ошибка, вы находитесь в середине задания - так что только часть - rollbackеd, и у вас есть данные в этих таблицах.

+0

Проблема заключается не в том, что транзакция отката или нет, хотя это то, что я обязательно добавлю позже, это система, которую я унаследовал. Проблема в том, что я не могу определить, какая ошибка была причиной этой проблемы. – fourdam

+0

По этой причине я рекомендую вам использовать 'TRANS' или' ARITHABORT'. В этом случае я думаю, что вы обязательно получите ERROR. У меня также есть аналогичная проблема с ошибкой «призрака». Я думаю, что введение транзакции будет «ловить» ошибку. Также проверяйте 'implicit' /' explicit' транзакции - я думаю, что источник ошибки «призрака» есть. –

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