在 [LinkServer] 尝试以 EXECUTE (@SQL) 形式执行 SQL 查询时,遍历链接服务器列表

问题描述 投票:0回答:1

我正在尝试执行以下 -

DECLARE @SQL nvarchar(max), @LinkServer nvarchar(200), @min INT=1, @max INT

drop table if exists #clients;
create table #clients (Id int identity(1,1), ClientName varchar(200), LinkServer varchar(200));

insert into #clients (ClientName, LinkServer) values ('abc', 'LinkServer1');
insert into #clients (ClientName, LinkServer) values ('xyz', 'LinkServer2');

set @max = (SELECT MAX(Id) FROM #clients)

WHILE(@min<=@max)
BEGIN
@SQL = 'select * from Table;'

SELECT @LinkServer=LinkServer FROM #clients WHERE ID=@min
EXECUTE (@SQL) AT [@LinkServer]

SET @min=@min+1
END

但是它将@LinkServer 读作一个字符。我想在多个服务器上运行此查询,但无法使用当前语法执行此操作。我只需要在 [LinkServer] 上使用 EXECUTE(@SQL)。

sql sql-server linked-server execute
1个回答
1
投票

你不能像那样参数化

AT linked_server_name
,它必须是文字。

您可以使用参数化的

EXEC
更轻松地做到这一点。没有多少人知道过程名称本身可以参数化。所以你只需要建立一个字符串
Server..sys.sp_executesql

注意服务器名称需要在

sysname
nvarchar(128)
中,并且您需要使用
QUOTENAME
引用它。另外,不要只是为了避免游标而使用
WHILE
,它很愚蠢,甚至比游标更低效。

DECLARE @proc nvarchar(1000);

DECLARE @crsr CURSOR;
SET @crsr = CURSOR FAST_FORWARD FOR
    SELECT procName = QUOTENAME(LinkServer) + '..sys.sp_executesql'
    FROM #clients;

OPEN @crsr;
WHILE(1=1)
BEGIN
    FETCH NEXT @crsrs INTO @proc;
    IF @@FETCH_STATUS <> 0
        BREAK;

    EXEC @proc N'select * from Table;'
END;

db<>小提琴

© www.soinside.com 2019 - 2024. All rights reserved.