zoukankan      html  css  js  c++  java
  • SQL Server 创建链接服务器

    遇到下列问题:

    线上服务器A,中转服务器B,本地服务器C

    数据在A上面,想在B上面操作类似 select * from [A].[database].table这样的SQL,不用去链接服务器,直接把处理结果导入B然后生成报表。

    结果报错如下:

    消息 7202,级别 11,状态 2,第 1 行
    在 sys.servers 中找不到服务器 'A'。请验证指定的服务器名称是否正确。如果需要,请执行存储过程 sp_addlinkedserver 以将服务器添加到 sys.servers。

    解决思路:问题很明显就是在B中没有服务A,奇怪了B上面的本地导入导出就可以,为什么这样不可以?仔细看了才发现B上面的sqlserver链接服务器列表确实

    不存在A。

    执行下面操作在B服务器上面创建A服务器连接,

    适用场景:对远程的DB进行操作。

    2000与2005对比:在SQL Server 2000版本中也有链接远程DB的SQL,但是功能比较弱,扩展性差,支持的查询比较简单。而SQL Server 2005版本的SSMS中已经有了 服务器对象->链接服务器 的功能点,用户首先创建一个远程DB的链接对象,之后就可以像本地表一样执行表的DML了。

    创建步骤:在SQL Server 2005版本打开SSMS,服务器对象->链接服务器->右击 新建链接服务器,在图2中是一种设置方式,也有其它的设置方式,比如:[图解]sqlserver中创建链接服务器,图3是安全性选项中设置远程数据库的账号和密码。

    (图1:新建链接) 

     

    (图2:设置链接) 

     

    (图3:设置帐号) 

     

    注意事项: 在MSSQL2005中Rpc的默认设置如图4所示, 需要把它设置为图5, 右键点击远程链接->属性->服务器选项->Rpc和Rpc Out,这两个值需要设置为True。

    (图4: 默认设置) 

     

    (图5: 正确设置) 

    但在MSSQL2008下不能直接修改链接服务器 'ETV2_LINK' 的RPC配置成TURE,可以通过语句修改如下:

     
    USE [master]
    GO
    EXEC master.dbo.sp_serveroption @server=N'ETV2_LINK', @optname=N'rpc', @optvalue=N'true'
    GO
    EXEC master.dbo.sp_serveroption @server=N'ETV2_LINK', @optname=N'rpc out', @optvalue=N'true'
    GO
     

    生成脚本:如果已经通过操作界面生成了 'ETV2_LINK' 的链接服务器,那么我们如果需要把它移植到其它数据库(部署、更新)的时候,就可以通过下面的方法来生产SQL脚本,你也可以通过修改SQL脚本来快速新建或修改链接服务器,比如修改@server链接服务器名称,修改@datasrc远程链接的数据库对象。

    (图6: 生成SQL脚本) 

    SQL Server 2005生成远程链接对象的SQL脚本:

     
    /****** 对象:  LinkedServer [ETV2_LINK]    脚本日期: 09/08/2010 17:36:11 ******/
    EXEC master.dbo.sp_addlinkedserver @server = N'ETV2_LINK', @srvproduct=N'ETV2_LINK', @provider=N'SQLNCLI', @datasrc=N'BWA035BWA035_2K5'
    GO
    EXEC master.dbo.sp_serveroption @server=N'ETV2_LINK', @optname=N'collation compatible', @optvalue=N'false'
    GO
    EXEC master.dbo.sp_serveroption @server=N'ETV2_LINK', @optname=N'data access', @optvalue=N'true'
    GO
    EXEC master.dbo.sp_serveroption @server=N'ETV2_LINK', @optname=N'dist', @optvalue=N'false'
    GO
    EXEC master.dbo.sp_serveroption @server=N'ETV2_LINK', @optname=N'pub', @optvalue=N'false'
    GO
    EXEC master.dbo.sp_serveroption @server=N'ETV2_LINK', @optname=N'rpc', @optvalue=N'true'
    GO
    EXEC master.dbo.sp_serveroption @server=N'ETV2_LINK', @optname=N'rpc out', @optvalue=N'true'
    GO
    EXEC master.dbo.sp_serveroption @server=N'ETV2_LINK', @optname=N'sub', @optvalue=N'false'
    GO
    EXEC master.dbo.sp_serveroption @server=N'ETV2_LINK', @optname=N'connect timeout', @optvalue=N'0'
    GO
    EXEC master.dbo.sp_serveroption @server=N'ETV2_LINK', @optname=N'collation name', @optvalue=null
    GO
    EXEC master.dbo.sp_serveroption @server=N'ETV2_LINK', @optname=N'lazy schema validation', @optvalue=N'false'
    GO
    EXEC master.dbo.sp_serveroption @server=N'ETV2_LINK', @optname=N'query timeout', @optvalue=N'0'
    GO
    EXEC master.dbo.sp_serveroption @server=N'ETV2_LINK', @optname=N'use remote collation', @optvalue=N'true'
     

    使用假设已经创建了名为ETV2_LINK的远程链接对象,那么你就可以像下面的方式来使用这个对象操作远程DB。

    使用场景1: 查询ETV2_LINK这个远程链接对象的[etV2_Online]数据库中VisiteLog_20100629表的数据。模板形如:Select * From [链接服务器名].[远程数据库名].[所有者].[表名]

    --查询远程DB表TableName
    select * from ETV2_LINK.[etV2_Online].dbo.VisiteLog_20100629

    使用场景2: 判断ETV2_LINK这个远程链接对象的[etV2_Online]数据库中是否存在名为VisiteLog_20100629的表。

     
    --注意:是sys.objects不是sysobjects
    --判断远程用户是否存在某张表
    IF EXISTS (SELECT * FROM ETV2_LINK.[etV2_Online].sys.objects WHERE name = N'VisiteLog_20100629' AND type in (N'U'))
    BEGIN
        --逻辑处理
        print '存在表'
    END
     

    使用场景3: 判断远程DB的[etV2_Online]数据库中是否存在名为VisiteLog_20100629的表。只不过这个表名是参数化的,可以通过传入的参数进行判断。这里只是简单的设置变量的值并使用OUT来返回变量。 

     
    --判断远程用户是否存在某张表(参数化表名),返回变量
    DECLARE @IsExistTable VARCHAR(10)
    DECLARE @Tablename VARCHAR(50)
    DECLARE @sqlString NVARCHAR(4000)
    SET @IsExistTable = 'False'
    SET @Tablename = 'VisiteLog_'+convert(varchar(9),getdate()-1,112) --例如VisiteLog_20100629
    SET @sqlString = 
    'IF EXISTS (SELECT * FROM ETV2_LINK.[etV2_Online].sys.objects WHERE name = N'''+@Tablename+''' AND type in (N''U''))
        set @IsExistTableOUT =''True'''
    EXEC sp_executesql @sqlString,N'@IsExistTableOUT varchar(10) OUTPUT',@IsExistTableOUT=@IsExistTable OUTPUT

    IF (@IsExistTable = 'True')--存在
    BEGIN
        --逻辑处理
        print '存在表'
    END
     

    补充: SQL Server 2000版本连接远程服务器的SQL脚本,更多相关脚步可以参考:在T-SQL语句中访问远程数据库(openrowset/opendatasource/openquery) 

    --方法1:
    select *  from openrowset('SQLOLEDB','server=192.168.0.67;uid=sa;pwd=password','SELECT * FROM BCM2.dbo.tbAppl')

    --方法2:
    select *  from openrowset('SQLOLEDB','192.168.0.67';'sa';'password','SELECT * FROM BCM2.dbo.tbAppl') 
  • 相关阅读:
    JAVA软件工程师应该具备哪些基本素质?
    java编程题(一)
    js继承之Object.create()
    【3D计算机图形学】变换矩阵、欧拉角、四元数
    JS的get和set使用示例
    深入浅析JavaScript中的constructor
    图片预加载之模拟img.load()
    threejs里面的vector3源码解析
    javascript事件轮询
    关于URL编码的一些结论
  • 原文地址:https://www.cnblogs.com/wanshutao/p/4137994.html
Copyright © 2011-2022 走看看