0

我有一个存储过程,它返回本地服务器上的 SQL 代理作业的详细信息。有一个主脚本使用 OPENQUERY 对生态系统中的每个 SQL 服务器调用此过程。在伪代码中,主脚本看起来像这样:

FOR EACH @LinkedServer in the list
    SET @SQL = 'INSERT #Results SELECT * FROM OPENQUERY(' + @LinkedServer + ',''EXEC ScriptToGetAgentJobInfo'')'
    EXEC sp_executesql @SQL
NEXT @LinkedServer

一些代理工作是从 SSRS 报告订阅创建的,因此它们的名称看起来很糟糕。为了将它们替换为作为订阅目标的报告的名称,我呼吁 上的 ReportServer 数据库@LinkedServer作为ScriptToGetAgentJobInfo.

然而,并不是每台服务器都包含一个 ReportServer 数据库,所以有时这种上诉会失败。为了解决这个失败,我有以下几行脚本:

DECLARE @Reports TABLE
( AgentJob      SYSNAME
 ,Reportname    NVARCHAR(128));

IF EXISTS(SELECT 1 FROM [master].[dbo].sysdatabases WHERE [name] = 'ReportServer')
BEGIN;
    INSERT @Reports(AgentJob,Reportname)
        SELECT Job.job_id, Report.[Name]
        FROM 
                    ReportServer.dbo.ReportSchedule AS ReportSched
        INNER JOIN               dbo.sysjobs        AS Job          ON CONVERT(SYSNAME,ReportSched.ScheduleID) = Job.[name]
        INNER JOIN  ReportServer.dbo.Subscriptions  AS Subscription ON ReportSched.SubscriptionID = Subscription.SubscriptionID
        INNER JOIN  ReportServer.dbo.[Catalog]      AS Report       ON Subscription.report_oid = Report.itemid;
END;

这个想法是,如果报告服务器数据库不存在,我可以避免对其进行任何调用,这会出错,但如果存在,我可以从中获取数据。然后,我将@Reports表格加入到我的 SQL 代理作业查询中,LEFT JOIN以显示相关报告的名称(如果有)。

当我在本地运行脚本时,所有这些都可以正常工作,但是当通过主过程调用它时,我收到一条错误消息Invalid object name 'ReportServer.dbo.ReportSchedule'

我可以通过使报表服务器选择语句“动态”(尽管它是完全静态的)并用另一个sp_executesql调用来调用它来解决这个问题,但我真的很讨厌这样做!

所以我的问题是这样的:为什么只有在远程调用脚本时才会出现错误,如果不求助于动态sql,如何避免它?

主脚本在 SQL Server 14.0 中编写和运行,而导致问题的链接服务器仅在 SQL Server 10.50 上。

4

0 回答 0