使用 INSERT INTO...EXEC AT 链接服务器进入临时表失败并显示消息 7391

Edg*_*ron 8 sql-server dynamic-sql t-sql linked-server temporary-tables

我正在使用 SQL Server 2014。我想执行EXEC (@remotecmd) AT [server_name];(@remotecmd 是动态 sql 而不是存储过程)到##eapb. 我的代码是

insert into ##eapb
EXEC (@remotecmd) AT [ADSQLDB3S\DEV];
Run Code Online (Sandbox Code Playgroud)

但我收到错误:

链接服务器“server_name”的 OLE DB 访问接口“SQLNCLI11”返回消息“事务管理器已禁用对远程/网络事务的支持。”。
    消息 7391,级别 16,状态 2,第 71 行
    由于链接服务器“server_name”的 OLE DB 提供程序“SQLNCLI11”无法开始分布式事务,因此无法执行该操作。

如果我删除insert into ##eapb,我没有错误。

链接服务器的RPC Out选项设置为True

Sol*_*zky 7

在我的测试中(对同一服务器上的另一个实例,而不是在单独的服务器上),如果我将启用 RPC 分布式事务提升的链接服务器选项设置为“假” ,这会起作用。您可以通过以下命令完成此操作:

EXEC master.dbo.sp_serveroption
       @server = N'{linked_server_name}',
       @optname = N'remote proc transaction promotion',
       @optvalue = N'false';
Run Code Online (Sandbox Code Playgroud)

这与分布式事务协调器 (MSDTC) 一起使用(ON(正在运行)和 OFF(已停止))。

如果您通常需要将“remote proc transaction Promotion”选项设置为“True”,并且如果将其设置为“False”允许它INSERT...EXEC工作,那么您可以设置另一个具有所有相同属性的链接服务器,除了这个选项是不同的。

禁用“远程 proc trans Promotion”的主要缺点是,它不是远程服务器上的事务。因此,如果在那里发生错误,您将不会在本地插入数据(显然),但是如果有任何 DML 语句远程运行,这些语句仍然可以提交(取决于它是单个语句还是多个语句)。尽管如此,您仍然可以/应该仍然对远程查询使用正确的事务处理(即使用TRY...CATCH构造):

CREATE TABLE #Local ([name] [sysname]);


INSERT INTO #Local ([name])
    EXEC (N'
BEGIN TRY
    BEGIN TRAN;
    SELECT [name] FROM sys.servers WHERE 1/0 = ''a'';
    COMMIT;
END TRY
BEGIN CATCH
    ROLLBACK TRAN;
    THROW;
END CATCH;
') AT [{linked_server_name}];
Run Code Online (Sandbox Code Playgroud)

PS 该RPC Out选项需要启用/True。上面没有提到这一点,因为根据对该问题的评论,此选项已正确设置。