Sql-Server

使用 INSERT INTO…EXEC AT 連結伺服器進入臨時表失敗並顯示 Msg 7391

  • February 28, 2020

我正在使用 SQL Server 2014。我想EXEC (@remotecmd) AT [server_name];##eapb. 我的程式碼是

insert into ##eapb
EXEC (@remotecmd) AT [ADSQLDB3S\DEV];

但我得到了錯誤:

連結伺服器“server_name”的 OLE DB 提供程序“SQLNCLI11”返回消息“事務管理器已禁用其對遠端/網路事務的支持。”。

    消息 7391,級別 16,狀態 2,第 71 行

    操作無法執行,因為連結伺服器“server_name”的 OLE DB 提供程序“SQLNCLI11”無法開始分佈式事務。

如果我刪除insert into ##eapb,我沒有錯誤。

連結伺服器的RPC Out選項設置為True

在我的測試中(針對同一伺服器上的另一個實例,而不是在單獨的伺服器上),如果我將啟用 RPC 的分佈式事務提升的連結伺服器選項設置為“False”,則此方法有效。您可以通過以下命令完成此操作:

EXEC master.dbo.sp_serveroption
      @server = N'{linked_server_name}',
      @optname = N'remote proc transaction promotion',
      @optvalue = N'false';

這與分佈式事務處理協調器 (MSDTC) 一起工作,同時開啟(執行)和關閉(停止)。

如果您通常需要將“remote proc transaction Promotion”選項設置為“True”,並且如果將其設置為“False”允許它INSERT...EXEC工作,那麼您可以設置另一個具有所有相同屬性的連結伺服器,除了這個選項是不同的。

禁用“remote 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}];

PS 該RPC Out選項需要啟用/真。上面沒有提到這一點,因為根據對該問題的評論,此選項已正確設置。

引用自:https://dba.stackexchange.com/questions/193727