因為業務的需求,需要用Linked Server從當前數據庫獲取遠端數據庫的 數據庫大小 以及 遠端數據庫的 表大小
關於Linked Server 連接,請看我的另一篇文檔:
http://blog.csdn.Net/zwxrain/archive/2007/01/18/1486304.ASPx
在操作中遇到以下幾個問題,並都以解決
問題一: 不可以直接對遠需數據庫操作 sp_spaceused 查看大小(數據庫大小和表大小)
sp_spaceused 的操用方法:
查看本地表大小
sp_spaceused ‘TableName’
查看遠端數據庫大小
Srv_MES.InsiteProdDG.dbo.sp_spaceused ‘TableName’
說明:
Srv_MES 為Linked Server , InsiteProdDG 為Linked Server 遠端的數據庫名。
查看遠端數據大小的錯誤描述:
Msg 7411, Level 16, State 1, Line 14
Server 'Srv_MES' is not configured for RPC.
解決方法:將Linked Server 的Rpc_Out 設成 True
問題2: 解決第一個問題,我們可以正常查詢遠端數據庫的表大小,但當然們將查詢結果保存到表時卻出現如下錯誤。
insert into @tb_size exec Srv_MES.InsiteProdDG.dbo.sp_spaceused ‘tb_name’
錯誤描述:
OLE DB provider "SQLNCLI" for linked server "Srv_MES" returned message "The transaction manager has disabled its support for remote/network transactions.".
Msg 7391, Level 16, State 2, Line 13
The Operation could not be performed because OLE DB provider "SQLNCLI" for linked server "Srv_MES" was unable to begin a distributed transaction.
原因:
由於開啟了事務,需要分布式事務協調器的支持。打開本機的控制面板 - 管理工具 - 服務,將兩台服務器上的 Distributed Transaction Coordinator (MSDTC) 服務開啟,注意 MSDTC 服務的登陸名必須選擇 NETWORK SERVICE 用戶。然後設置高級選項,運行 dcomcnfg.exe ,進入組件服務,選擇我的電腦右鍵屬性,MSDTC - 安全配置,勾選:網絡DTC訪問,允許入站,允許出站,並且不要求進行驗證。其他的可以根據需要選擇,不是必須選項。
解決:
SQL 代碼部分:
---Linked Server 獲取遠端數據庫的大小----
Create procedure [dbo].[Proc_DBA_Database_Size]
as
Declare @l_datetime varchar(20)
set @l_datetime = convert(varchar(20),getdate(),120)
insert into TB_DBA_Database_Size
select -- fileid,
@l_datetime as Date_Time,
'InsiteProdDG' [Database Name] ,
cast(sum(size)*8/1024. as decimal(10,2)) [DB Size],
'MB' Size_Type
-- name logic filename,
-- filename physics filename
from Srv_MES.InsiteProdDG.dbo.sysfiles
---Linked Server 獲取遠端數據庫表的大小----
Create procedure [dbo].[Proc_DBA_MES_Table_Size]
as
Declare @tb_name varchar(50)
Declare @tb_list table
(
tb_name varchar(50)
)
declare @tb_size table
(
name varchar(50),
rows varchar(50),
Reserved varchar(50),
Data varchar(50),
Index_Size varchar(50),
Unused varchar(50)
)
declare cur_tb_list cursor for
select name
from dbo.sysobjects
where objectproperty(id, N'istable') = 1
and name not like N'#%%'
order by name
open cur_tb_list
fetch Next from cur_tb_list
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 into @tb_size exec Srv_MES.InsiteProdDG.dbo.sp_spaceused @tb_name
fetch Next from cur_tb_list
into @tb_name
end
insert into TB_DBA_Database_Table_Size
select convert(varchar(20),getdate(),120) as date_time,*
from @tb_size
close cur_tb_list
deallocate cur_tb_list