Iterate through list of linkservers while trying to execute SQL query as EXECUTE (@SQL) at [LinkServer]

huangapple go评论66阅读模式
英文:

Iterate through list of linkservers while trying to execute SQL query as EXECUTE (@SQL) at [LinkServer]

问题

I want to run this query on multiple servers, but with the current syntax, it interprets @LinkServer as a character. I need to use EXECUTE(@SQL) AT [LinkServer] only.

英文:

I am trying to execute the below -

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

But it reads @LinkServer as a character. I want to run this query on multiple server, but unable to do so with the current syntax. I need to use EXECUTE(@SQL) AT [LinkServer] only.

答案1

得分: 2

不能像那样将 AT linked_server_name 参数化,它必须是一个文字值。

可以更轻松地使用参数化的 EXEC。很少有人知道过程名称本身可以作为参数化。所以你只需要构建一个字符串 Server..sys.sp_executesql

请注意,服务器名称需要在 sysnamenvarchar(128) 中,并且需要使用 QUOTENAME 进行引用。此外,不要使用 WHILE 只是为了避免使用游标,这很愚蠢,甚至比游标更低效。

英文:

You can't parameterize the AT linked_server_name like that, it has to be a literal.

You can do this more easily using a parameterized EXEC. Not many people know that the procedure name itself can be parameterized. So you just need to build a string Server..sys.sp_executesql

Note that the server name needs to be in a sysname or nvarchar(128), and you need to quote it using QUOTENAME. Also, don't use WHILE just to avoid a cursor, it's silly and even more inefficient than a cursor.

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 @crsr INTO @proc;
    IF @@FETCH_STATUS <> 0
        BREAK;

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

db<>fiddle

huangapple
  • 本文由 发表于 2023年5月11日 19:38:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76227235.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定