我在执行存储过程的表上有一个触发器。执行的存储过程具有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
答案 0 :(得分:0)
我能够修改存储过程以不使用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