Catch不会将error_message()传递给在catch内部

时间:2019-06-04 10:42:07

标签: sql stored-procedures sql-server-2012 try-catch

我创建了一个小的日志记录框架,以便可以轻松调用诸如spLog或spLogError之类的存储过程。

存储过程和表都驻留在名为Logging的单独数据库中。

现在我使用的代码如下:

if OBJECT_ID('dbo.testLogProcLinkedServer') is not null
    drop procedure dbo.testLogProcLinkedServer;
go

CREATE PROCEDURE [dbo].[testLogProcLinkedServer]
AS
BEGIN
    set nocount on;

    declare @msg nvarchar(max),
            @dbId int = db_id();

    begin try
        declare @i int;

        set @i = 1 / 0;
    end try
    begin catch
        exec [MyLinkedServer].[Logging].dbo.spLogError  @objectId = @@PROCID, 
                                                        @databaseId = @dbId, 
                                                        @message = N'Testing catch errors, check field ErrorMessage for more information.';
    end catch
end
go

exec dbo.testLogProcLinkedServer;

现在问题是ERROR_MESSAGE()没有进入spLogError,它为NULL。但是,当我删除MyLinkedServer时(在我的开发环境中,数据库位于同一台服务器上,因此我可以执行此操作),ERROR_MESSAGE()可用,并且一切都按预期工作。

在Google上查找“ tsql catch链接的服务器”时。 我发现这个问题: Catching Errors through a linked server with severity < 20

但是,这个问题和我的问题的主要区别在于,大多数主题都涉及从远程过程调用中捕获错误,但是我不想从远程过程调用中捕获某些问题。 我想将错误数据发送给它并写入相应的表。

任何人都可以指出是什么原因造成的吗?

1 个答案:

答案 0 :(得分:1)

ERROR_MESSAGE()和其他错误上下文函数仅在本地CATCH块中可用。远程过程忽略了从CATCH块中调用它的事实,并且无法访问错误上下文。

出于日志记录的目的,您需要将该值作为参数值传递到远程spLogError

BEGIN CATCH
    @msg = N'Testing catch errors, ErrorMessage value is: '
        + ERROR_MESSAGE();
    EXEC [MyLinkedServer].[Logging].dbo.spLogError  @objectId = @@PROCID, 
                                                    @databaseId = @dbId, 
                                                    @message = @msg;
END CATCH;