透過 Linked Server 查詢遠端資料庫與資料表大小,是跨伺服器監控常見需求。本文記錄兩大經典錯誤 (RPC 未啟用、分散式交易失敗) 及解決步驟,並提供完整預存程序碼,助你快速建立遠端空間監控。
現象:執行 EXEC Srv_MES.InsiteProdDG.dbo.sp_spaceused 'TableName' 報錯。
原因:Linked Server 預設關閉 RPC 輸出。
解決:SSMS → 連結伺服器屬性 → 伺服器選項 → RPC Out = True。

現象:INSERT INTO @tb_size EXEC Srv_MES...sp_spaceused 失敗,提示分散式交易不支援。
原因:INSERT...EXEC 隱含交易,需 MSDTC 協調。
解決 (雙向伺服器均需設定):
dcomcnfg.exe → 元件服務 → 我的電腦右鍵屬性 → MSDTC → 安全性設定 → 勾選:網路 DTC 存取、允許輸入、允許輸出、不要求驗證。
CREATE PROC [dbo].[Proc_DBA_Database_Size] AS DECLARE @dt VARCHAR(20) = CONVERT(VARCHAR(20), GETDATE(), 120); INSERT INTO TB_DBA_Database_Size SELECT @dt, 'InsiteProdDG', CAST(SUM(size)*8/1024.0 AS DECIMAL(10,2)), 'MB' FROM Srv_MES.InsiteProdDG.dbo.sysfiles;
CREATE PROC [dbo].[Proc_DBA_MES_Table_Size] AS
DECLARE @tb_name VARCHAR(50), @tb_list TABLE (tb_name VARCHAR(50)),
@tb_size TABLE (name VARCHAR(50), rows VARCHAR(50), Reserved VARCHAR(50),
Data VARCHAR(50), Index_Size VARCHAR(50), Unused VARCHAR(50));
DECLARE cur CURSOR FOR
SELECT name FROM dbo.sysobjects
WHERE OBJECTPROPERTY(id, N'IsTable') = 1 AND name NOT LIKE N'#%%'
ORDER BY name;
OPEN cur; FETCH NEXT FROM cur INTO @tb_name;
WHILE @@FETCH_STATUS = 0
BEGIN
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(@tb_name) AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
INSERT @tb_size EXEC Srv_MES.InsiteProdDG.dbo.sp_spaceused @tb_name;
FETCH NEXT FROM cur INTO @tb_name;
END
CLOSE cur; DEALLOCATE cur;
INSERT INTO TB_DBA_Database_Table_Size
SELECT CONVERT(VARCHAR(20), GETDATE(), 120), * FROM @tb_size;
sp_spaceused 回傳字串欄位 (含 'KB' 字樣),後續計算成長量時需 LEFT(..., LEN()-2) 移除單位再轉數值。sysfiles/sysobjects 結構可能不同。