一、背景
我們的數據庫比較多,它們提供了外網的訪問,我現在想對這些數據庫進行一些管理,獲取這些數據庫的一些信息,我們可以通過什么方式實現呢?
在SQL Server2005版本之后有一個叫做鏈接服務器的新功能,基本的操作可以參考:
SQL Server 2005鏈接服務器,我們就通過這個鏈接服務器來獲取我們需要的數據,但是我們的服務器比較多,這個批量創建鏈接服務器和批量刪除鏈接服務器就呼之欲出了。
二、設計過程
設計簡述:創建如下圖的表結構,LinkName保存遠程鏈接的別名,LinkName2是創建鏈接方式2的一個補充字段,LinkIP代表遠程服務器的地址,如果有端口的還需要加上端口。
這里為什么要設計成LinkName與LinkName2並存呢?這是因為我們在T-SQL使用遠程鏈接的時候是通過別名的,我在進行兩種方式的切換,只要修改調換下這兩個字段的名稱,並且去存儲過程sp_CreateLink注釋方式1的代碼,恢復方式2的代碼;
(圖1:LinkConfig表,鏈接方式1)
(圖2:LinkConfig表,鏈接方式2)
(圖3:鏈接方式1的屬性)
(圖4:鏈接方式2的屬性)
詳細代碼:創建表LinkConfig、批量創建鏈接服務器存儲過程、批量刪除鏈接服務器存儲過程。
--創建表 CREATE TABLE [dbo].[LinkConfig]( [Id] [int] IDENTITY(1,1) NOT NULL, [LinkName] [nvarchar](50) NULL, [LinkName2] [nvarchar](50) NULL, [LinkIP] [nvarchar](50) NULL, [LinkSa] [nvarchar](50) NULL, [LinkPassword] [nvarchar](50) NULL, [State] [int] NULL CONSTRAINT [DF_LinkConfig_State] DEFAULT ((0)), CONSTRAINT [PK_LinkConfig] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]
--創建遠程鏈接sp -- ============================================= -- Author: <Viajar> -- Create date: <2012.01.05> -- Description: <創建遠程鏈接> -- ============================================= CREATE PROCEDURE [dbo].[sp_CreateLink] AS BEGIN SET NOCOUNT ON; --創建遠程鏈接 DECLARE @linkname VARCHAR(100) DECLARE @linkip VARCHAR(100) DECLARE @linksa VARCHAR(100) DECLARE @linkpassword VARCHAR(100) DECLARE @isexists VARCHAR(10) DECLARE @sql NVARCHAR(4000) SET @isexists = 'False' DECLARE @itemCur CURSOR SET @itemCur = CURSOR FOR SELECT [LinkName],[LinkIP],[LinkSa],[LinkPassword] FROM dbo.LinkConfig WHERE State =1 OPEN @itemCur FETCH NEXT FROM @itemCur INTO @linkname,@linkip,@linksa,@linkpassword WHILE @@FETCH_STATUS=0 BEGIN --正在處理 PRINT @linkname --判斷是否存在 set @sql = N'IF EXISTS (SELECT * FROM sys.servers WHERE name = '''+ @linkname + ''') begin set @IsExistsOUT = ''True'' end' exec sp_executesql @sql,N'@IsExistsOUT varchar(10) OUTPUT',@IsExistsOUT=@isexists OUTPUT --不存在 IF(@IsExists = 'False') BEGIN --創建鏈接方式 SET @sql = ' EXEC master.dbo.sp_addlinkedserver @server = N'''+@linkname+''', @srvproduct=N''SQL Server''' EXEC(@sql) --設置密碼 SET @sql = ' EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname = N'''+@linkname+''', @locallogin = NULL , @useself = N''False'', @rmtuser = N'''+@linksa+''', @rmtpassword = N'''+@linkpassword+'''' EXEC(@sql) -- --創建鏈接方式 -- SET @sql = ' -- EXEC master.dbo.sp_addlinkedserver @server = N'''+@linkname+''', @srvproduct=N'''+@linkname+''', @provider=N''SQLNCLI'', @datasrc=N'''+@linkip+'''' -- EXEC(@sql) -- -- --設置密碼 -- SET @sql = ' -- EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname = N'''+@linkname+''', @locallogin = NULL , @useself = N''False'', @rmtuser = N'''+@linksa+''', @rmtpassword = N'''+@linkpassword+'''' -- EXEC(@sql) -- -- --設置屬性 -- SET @sql = ' -- EXEC master.dbo.sp_serveroption @server=N'''+@linkname+''', @optname=N''rpc'', @optvalue=N''true'' -- ; -- EXEC master.dbo.sp_serveroption @server=N'''+@linkname+''', @optname=N''rpc out'', @optvalue=N''true'' -- ' -- EXEC(@sql) END SET @isexists = 'False' FETCH NEXT FROM @itemCur INTO @linkname,@linkip,@linksa,@linkpassword END CLOSE @itemCur DEALLOCATE @itemCur END
--刪除遠程鏈接sp -- ============================================= -- Author: <Viajar> -- Create date: <2012.01.05> -- Description: <刪除遠程鏈接> -- ============================================= ALTER PROCEDURE [dbo].[sp_DropLink] AS BEGIN SET NOCOUNT ON; --刪除遠程鏈接 DECLARE @linkname VARCHAR(100) DECLARE @linkip VARCHAR(100) DECLARE @linksa VARCHAR(100) DECLARE @linkpassword VARCHAR(100) DECLARE @isexists VARCHAR(10) DECLARE @sql NVARCHAR(4000) SET @isexists = 'False' DECLARE @itemCur CURSOR SET @itemCur = CURSOR FOR SELECT [LinkName],[LinkIP],[LinkSa],[LinkPassword] FROM dbo.LinkConfig WHERE State =1 OPEN @itemCur FETCH NEXT FROM @itemCur INTO @linkname,@linkip,@linksa,@linkpassword WHILE @@FETCH_STATUS=0 BEGIN --正在處理 PRINT @linkname --判斷是否存在 set @sql = N'IF EXISTS (SELECT * FROM sys.servers WHERE name = '''+ @linkname + ''') begin set @IsExistsOUT = ''True'' end' exec sp_executesql @sql,N'@IsExistsOUT varchar(10) OUTPUT',@IsExistsOUT=@isexists OUTPUT --不存在 IF(@IsExists = 'True') BEGIN --刪除鏈接 SET @sql = ' IF EXISTS (SELECT srv.name FROM sys.servers srv WHERE srv.server_id != 0 AND srv.name = N'''+@linkname+''') BEGIN EXEC master.dbo.sp_dropserver @server=N'''+@linkname+''', @droplogins=''droplogins'' END' EXEC(@sql) END SET @isexists = 'False' FETCH NEXT FROM @itemCur INTO @linkname,@linkip,@linksa,@linkpassword END CLOSE @itemCur DEALLOCATE @itemCur END
三、注意事項
1. 進行方式1與方式2的切換,需要如圖1、圖2的表字段名稱進行修改,並且去存儲過程sp_CreateLink注釋方式1的代碼,恢復方式2的代碼;
2. 在需要修改表記錄之前需要先刪除所有鏈接服務器(執行存儲過程sp_DropLink),再創建鏈接服務器;(執行存儲過程sp_CreateLink);