遍历 SQL Server 中的服务器列表

Posted

技术标签:

【中文标题】遍历 SQL Server 中的服务器列表【英文标题】:Iterate through a list of servers in SQL Server 【发布时间】:2021-07-21 12:07:42 【问题描述】:

我有一个类似于下面的脚本并得到“在 sys.servers 中找不到服务器 '@CURSERVER'。验证是否指定了正确的服务器名称。如有必要,执行存储过程 sp_addlinkedserver 以将服务器添加到 sys。服务器。”

我正在尝试从所有链接服务器获取 SQL Server 代理作业。我认为我的链接服务器没有问题,但我可以不将服务器名称作为变量吗?

 -- Declare your array table variable  
DECLARE @SERVERS table (serverName nvarchar(50), ARRAYINDEX int identity(1,1) )  
  
-- Add values to your array table, these are the values which you need to look for in your database  
INSERT INTO @SERVERS (serverName)  
   VALUES  
('server1'), ('server2'), ('server3')
  
DECLARE @INDEXVAR INT = 1
DECLARE @TOTALCOUNT int  
DECLARE @CURSERVER nvarchar (50)  
SELECT @TOTALCOUNT= COUNT(*) FROM @SERVERS 
WHILE @INDEXVAR < @TOTALCOUNT  
BEGIN    
    -- Get value of current indexed server  
    SELECT @CURSERVER = serverName from @SERVERS where ARRAYINDEX = @INDEXVAR  
  
    -- Get details of jobs on the server  
    BEGIN  
        SELECT  
            * FROM [@CURSERVER].[msdb].[dbo].[sysjobs] 
        SET @INDEXVAR += 1
    END  
END  

【问题讨论】:

参数用于传递值,而不是像服务器、数据库、模式或对象这样的对象。您不能使用参数代替实际的对象名称。错误说没有链接服务器的名称是确切的字符串@CURSERVER 这有点难看,但您可以使用EXEC(取决于权限)将语句作为动态 SQL 运行 为什么不使用注册服务器并同时针对所有实例运行它? @Larnu 这看起来也是个不错的方法! 【参考方案1】:

您不能将变量用作标识符(服务器名称、数据库名称、表名称等)。而是构建动态 SQL 语句并执行。

下面是一个示例,包括对原始脚本的更正和改进。

DECLARE @SERVERS table (serverName nvarchar(50), ARRAYINDEX int identity(1,1) )  
  
-- Add values to your array table, these are the values which you need to look for in your database  
INSERT INTO @SERVERS (serverName)  
   VALUES  
    ('server1'), ('server2'), ('server3');
DECLARE @TOTALCOUNT int = @@ROWCOUNT;
DECLARE @SQL nvarchar(MAX);
DECLARE @INDEXVAR INT = 1;
DECLARE @CURSERVER sysname 

WHILE @INDEXVAR <= @TOTALCOUNT  
BEGIN    
    -- Get value of current indexed server  
    SELECT @CURSERVER = serverName from @SERVERS where ARRAYINDEX = @INDEXVAR;  
  
    -- Get details of jobs on the server  
    BEGIN  
        SET @SQL = N'SELECT * FROM ' + QUOTENAME(@CURSERVER) + N'.[msdb].[dbo].[sysjobs];';
        --PRINT @SQL;
        EXEC sp_executesql @SQL;
        SET @INDEXVAR += 1;
    END;  
END;

【讨论】:

这就像一个魅力!只是使用更复杂的 SQL 语句会有点混乱。感谢您也对我的脚本进行了一些改进!

以上是关于遍历 SQL Server 中的服务器列表的主要内容,如果未能解决你的问题,请参考以下文章

只有在使用列列表并且 IDENTITY_INSERT 为 ON SQL Server 时,才能为表中的标识列指定显式值

SQL Server - 将表中的某些列镜像到同一服务器上的另一个数据库,无需复制

SQL Server报错:选择列表中的列无效,因为该列没有包含在聚合函数或 GROUP BY 子句中

SQL 服务器查询以获取表中的列列表以及数据类型、NOT NULL 和 PRIMARY KEY 约束

将csv上传到sql server时,“给定的ColumnMapping与源或目标中的任何列都不匹配”

启动 SQL Server 管理 Studio 在 SQL Server 2008R2 中的错误消息:"无法读取此系统上以前注册的服务器的列表" 解决方法