0

我需要在链接服务器(SQL Server 2005)上同步执行三个动态 SQL 语句,如下所示:

declare @statement nvarchar(max);

set @statement = 'exec ' + @server_name + '.' + @database_name + '.dbo.Foo;exec ' + @server_name + '.' + @database_name + '.dbo.Bar;exec ' + @server_name + '.' + @database_name + '.dbo.BigTime';

exec sp_executesql @statement;

为了测试这一点,我有一个链接到自身的链接服务器设置。

当执行这个本地(通过删除@server_name)时,使用 SQL Profiler 我看到它作为一个语句执行得很好。但是,当我通过链接服务器(使用@server_name变量)执行此操作时,我在 SQL Profiler 中看到每个语句都单独执行,并在每个语句sp_reset_connection之后执行。

跟踪看起来像这样:

Audit Login ....
exec database.dbo.Foo
exec sp_reset_connection
Audit Logout
Audit Login ....
exec database.dbo.Bar
exec sp_reset_connection
Audit Logout
Audit Login ....
exec database.dbo.BigTime
exec sp_reset_connection
Audit Logout

这给我带来了问题。为什么我可以指定 SQL Serversp_reset_connection在语句之间不调用?

4

5 回答 5

3
DECLARE @sql  nvarchar(max),
        @exec nvarchar(800) = QUOTENAME(@server_name)
                     + N'.' + QUOTENAME(@databaseName);

SET @sql = N'EXEC dbo.Foo;'
         + N'EXEC dbo.Bar;'
         + N'EXEC dbo.BigTime;';

EXEC @exec @sql;
于 2009-11-19T23:49:21.987 回答
1

You are executing three calls to three linked servers, the result is exactly what you should be expecting (even if the 3 linked servers are not distinct). To achieve what describe, execute the calls as you describe: execute three procedures on one linked server:

linkedserver.master.dbo.sp_ExecuteSQL N'
  exec dbname.dbo.Foo; 
  exec dbname.dbo.Bar; 
  exec dbname.dbo.BigTime;';

All you have to do is wrap this around in a dynamic built SQL:

declare @remoteStatement nvarchar(max), @localStatement nvarchar(max);
set @remoteStatement = N'exec ' + @database_name + N'.dbo.Foo; 
    exec ' + @database_name + N'.dbo.Bar; 
    exec '+ @database_name + N'.dbo.BigTime';
set @localStatement = @server_name + N'.master.dbo.sp_executesql @remoteStatement;';

exec sp_executesql @localStatement, N'@remoteStatement nvarchar(max)', @remoteStatement;
于 2009-11-19T23:47:27.780 回答
0

你能不能在链接服务器上创建一个单独的 SP 来调用另外 3 个然后只调用那个?

为什么重置连接会导致问题?每个 SP 是否使用某种特殊类型的连接持久存储,例如临时表或其他东西?

于 2009-11-19T23:34:13.317 回答
0

This may help:

BEGIN DISTRIBUTED TRANSACTION
 your stuff here
COMMIT TRANSACTION

For this you will need distributed transaction coordinator running.

于 2009-11-19T23:47:28.457 回答
0

根据 Remus 的回答,但避免使用sp_setnetname. YMMV。

一天或两天前有人问过这个问题:Fully qualified table names with SP_ExecuteSql to access remote server

于 2009-11-20T05:00:29.497 回答