我正在尝试执行以下 -
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)。
你不能像那样参数化
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;