Триггер SQL - подтверждение обновления и блок процедуры CATCH - PullRequest
0 голосов
/ 17 октября 2018

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

При сбое хранимой процедуры появляется следующая ошибка:

The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction.

Как мне сделать так, чтобы обновление было зафиксировано и также выполнялся CATCH в хранимой процедуре?Если я добавлю:

IF @@TRANCOUNT > 0 
ROLLBACK TRAN

к хранимой процедуре, то получу следующую ошибку:

The transaction ended in the trigger. The batch has been aborted.

Триггер:

ALTER TRIGGER [dbo].[trigger123] ON [dbo].[tbl321]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF UPDATE (status) 
BEGIN

 IF EXISTS (--some condition)
BEGIN
EXEC SProc 
END

END
END

SProc:

ALTER PROCEDURE [dbo].[SProc ]
AS  
BEGIN  

DECLARE @ErrorMessage NVARCHAR(4000);
DECLARE @ErrorSeverity INT;
DECLARE @ErrorState INT;

BEGIN TRY

   select @sql = '
   declare @error1 varchar(255),
   @error2 varchar(255),
   @error3 varchar(255)

   Exec SomeDB.DBO.ConfirmStatus  ''A10594'',@error1 output,@error2 output,@error3 output

   if ISNULL(@error1,0) <> 0
   begin
        set @error1 = ISNULL(@error2,'''') + '' '' + ISNULL(@error3,'''') + '' '' + ISNULL(@error1,0)
        RAISERROR (@error1, 16, 1)
   end'
   from jobs j

   exec(@sql) at [linked_server]

   update status
    set status_prev = 1

END TRY

BEGIN CATCH

SELECT
@ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE()

INSERT INTO error_log (error_datetime, [error_message])
SELECT
    GETDATE(),
    'Msg: ' + ISNULL(CONVERT(VARCHAR, ERROR_NUMBER()), 'N/A') + ', Level: ' + ISNULL(CONVERT(VARCHAR, @ErrorSeverity), 'N/A') + ', Line: ' + ISNULL(CONVERT(VARCHAR, ERROR_LINE()), 'N/A') + ', Error: ' + ISNULL(@ErrorMessage, 'N/A')

END CATCH
END

1 Ответ

0 голосов
/ 17 октября 2018

Мне удалось изменить мою хранимую процедуру, чтобы она не использовала try / catch.Это дает мне то, что мне нужно.

ALTER PROCEDURE [dbo].[SProc ]
AS  
BEGIN  

DECLARE @error table (error1 varchar(255))

DECLARE @ErrorMessage NVARCHAR(4000);
DECLARE @ErrorSeverity INT;
DECLARE @ErrorState INT;

BEGIN TRY

   select @sql = '
   declare @error1 varchar(255),
   @error2 varchar(255),
   @error3 varchar(255)

   Exec SomeDB.DBO.ConfirmStatus  ''A10594'',@error1 output,@error2 output,@error3 output

   if ISNULL(@error1,0) <> 0
   begin
        set @error1 = ISNULL(@error2,'''') + '' '' + ISNULL(@error3,'''') + '' '' + ISNULL(@error1,0)
        select @error1
   end'
   from jobs j

insert into @error
exec(@sql) at [linked_server]

if exists (select top 1 error1 from @error)
   begin

INSERT INTO error_log (error_datetime, [error_message])
SELECT
    GETDATE(),
    (select top 1 error1 from @error)

else
   update status
    set status_prev = 1

END
...