SQL Server 游標運用:批量創建、刪除鏈接服務器


一、背景

我們的數據庫比較多,它們提供了外網的訪問,我現在想對這些數據庫進行一些管理,獲取這些數據庫的一些信息,我們可以通過什么方式實現呢?

在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); 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM