从SQL Server中的两个不同服务器中选择数据


363

如何从SQL Server中两个不同服务器上的两个不同数据库中的同一查询中选择数据?


6
Eric和Raging Bull的答案非常方便。我能够使用它来将大量数据从DEV复制到PROD,减少时间从5个小时到18个小时,最短到17秒。
克里斯·奥尔德里奇

@Eric,为编辑一个边际模棱两可的问题并使之成为170个代表问题而表示敬意:)
Eric Wu

Answers:


345

您正在寻找的是链接服务器。您可以从“对象资源管理器”树中的以下位置在SSMS中找到它们:

Server Objects-->Linked Servers

或者您可以使用sp_addlinkedserver

您只需要设置一个。一旦有了它,就可以像这样在另一台服务器上调用一个表:

select
    *
from
    LocalTable,
    [OtherServerName].[OtherDB].[dbo].[OtherTable]

请注意,所有者并不总是dbo,因此请确保将其替换为您使用的任何架构。


13
没有链接服务器,我们可以做到吗?
Steam

5
@ Eric,SSMS中的服务器对象在哪里?
Tsahi Asher 2014年

9
@TsahiAsher-连接到服务器时,服务器对象是对象资源管理器树中的文件夹。
埃里克(Eric)

2
如果不知道,您也可以省略该模式以使用默认值。例如[OtherServerName].[OtherDB]..[OtherTable],最好将其包括在内(如果已知)。
汤姆·鲍尔斯

92

您可以使用链接服务器来完成。

通常,链接服务器配置为使数据库引擎能够执行Transact-SQL语句,该语句包括SQL Server的另一个实例或另一个数据库产品(如Oracle)中的表。可以将许多类型的OLE DB数据源配置为链接服务器,包括Microsoft Access和Excel。

链接服务器具有以下优点:

  • 从SQL Server外部访问数据的能力。
  • 能够在整个企业的异构数据源上发布分布式查询,更新,命令和事务。
  • 类似地处理各种数据源的能力。

阅读有关链接服务器的更多信息。

请按照以下步骤创建链接服务器:

  1. 服务器对象->链接服务器->新链接服务器

  2. 提供远程服务器名称。

  3. 选择远程服务器类型(SQL Server或其他)。

  4. 选择安全性->使用此安全性上下文进行设置,并提供远程服务器的登录名和密码。

  5. 单击确定,您就完成了!

是创建链接服务器的简单教程。

要么

您可以使用查询添加链接服务器。

句法:

sp_addlinkedserver [ @server= ] 'server' [ , [ @srvproduct= ] 'product_name' ] 
     [ , [ @provider= ] 'provider_name' ]
     [ , [ @datasrc= ] 'data_source' ] 
     [ , [ @location= ] 'location' ] 
     [ , [ @provstr= ] 'provider_string' ] 
     [ , [ @catalog= ] 'catalog' ] 

了解有关sp_addlinkedserver的更多信息。

您只需创建链接服务器一次。创建链接服务器后,我们可以按以下方式查询它:

select * from LinkedServerName.DatabaseName.OwnerName.TableName

注意:有关如何使服务器名不是主机名/端口的信息,请参见此处
理查德

1
提示,如果您在使用sp_addlinkedserver时遇到麻烦。在对话框中创建服务器-确保其正常工作-然后右键单击该连接,然后选择
scrip

25
SELECT
        *
FROM
        [SERVER2NAME].[THEDB].[THEOWNER].[THETABLE]

您还可以查看使用链接服务器。链接服务器也可以是其他类型的数据源,例如DB2平台。这是一种尝试从SQL Server TSQL或Sproc调用访问DB2的方法...


2
这种方法会一直有效吗?在哪些情况下可能会失败?
2014年

3
确认这在我的环境中失败,错误提示我需要使用addlinkedserver
gorlaz

1
无需使用链接服务器,这对任何人都有效吗?
Doug S

测试并收到的错误是Could not find server '88.208.229.164' in sys.servers. Verify that the correct server name was specified. If necessary, execute the stored procedure sp_addlinkedserver to add the server to sys.servers.
WhatsThePoint '18

22

跨2个不同数据库的查询是分布式查询。这是一些技术以及利弊的列表:

  1. 链接服务器:比SQL Server复制提供的访问更广泛的数据源
  2. 链接服务器:连接不支持复制或需要临时访问的数据源
  3. 链接服务器:性能比OPENDATASOURCE或OPENROWSET好
  4. OPENDATASOURCEOPENROWSET函数:方便用于临时从数据源检索数据。OPENROWSET还具有大量功能,可能/可能不需要格式文件,这可能很麻烦
  5. OPENQUERY:不支持变量
  6. 所有的T-SQL的解决方案。相对容易实施和设置
  7. 所有这些都取决于源和目标之间的连接,这可能会影响性能和可伸缩性

OPENQUERY仍然需要链接的服务器,其中如OPENDATASOURCE不
CJ

16

尝试这个:

SELECT * FROM OPENROWSET('SQLNCLI', 'Server=YOUR SERVER;Trusted_Connection=yes;','SELECT * FROM Table1') AS a
UNION
SELECT * FROM OPENROWSET('SQLNCLI', 'Server=ANOTHER SERVER;Trusted_Connection=yes;','SELECT * FROM Table1') AS a

16

这些都是很好的答案,但是缺少这个答案,它有自己的强大用途。可能不符合OP的要求,但是问题很模糊,我觉得其他人可能会在这里找到自己的方式。基本上,您可以使用1个窗口同时对多个服务器运行查询,方法如下:

在SSMS中,打开“注册服务器”,然后在“ 本地服务器组”下创建一个服务器组

在此组下,为要查询的每个服务器创建“ 新服务器注册 ”。如果数据库名称不同,请确保在属性中为每个数据库设置默认值。

现在返回到您在第一步中创建的组,右键单击并选择“新建查询”。将打开一个新的查询窗口,并且您运行的任何查询都将在组中的每台服务器上执行。结果显示在单个数据集中,并带有一个额外的列名,该列名指示记录来自哪个服务器。如果使用状态栏,您会注意到服务器名称被替换为多个


2
这似乎假设查询在所有数据库上使用相同的表。(对于sys.tables这样的标准表来说,这很好,但对于dbo.mycustomers这样的定制表来说,这不太可能)
Dennis Jaheruddin

由于它是“来自两个不同数据库的相同查询”,因此很可能具有相同的表。但是,是的,我通常将这种方法用于安装在多台服务器上的生产系统以及查询MSDB表。
保罗

真的很酷的功能。缺点是结果集的架构必须匹配,因为它执行两次查询并同时合并所有查询。如果您可以引用SQL本身内的服务器(如链接服务器),那将是很好的选择,即使您不能加入结果集并且必须构造这些集以分别进行评估也是如此。
克罗斯,

1
@Kross,您可以。创建一个#output表,基于@@ SERVERNAME进行逻辑,然后将数据填充到#output中,然后在其上进行选择。我通过从具有不同级别/列信息的SQL2000和SQL2008R2计算机中查询日志信息做了类似的事情,但是我使用的是服务器版本变量,而不是@@ SERVERNAME。
保罗

9

将SQL_server 2008连接到托管在远程服务器中的SQL_server 2016时,我遇到了同样的问题。其他答案对我没有直接作用。我在这里写下经过调整的解决方案,因为我认为这可能对其他人有用。

远程IP db连接的扩展答案:

步骤1:链接服务器

EXEC sp_addlinkedserver @server='SRV_NAME',
   @srvproduct=N'',
   @provider=N'SQLNCLI',   
   @datasrc=N'aaa.bbb.ccc.ddd';

EXEC sp_addlinkedsrvlogin 'SRV_NAME', 'false', NULL, 'your_remote_db_login_user', 'your_remote_db_login_password'

... SRV_NAME发明的名称在哪里 我们将使用它来从查询中引用远程服务器。aaa.bbb.ccc.ddd是托管SQLserver数据库的远程服务器的ip地址。

步骤2:运行查询 例如:

SELECT * FROM [SRV_NAME].your_remote_db_name.dbo.your_table

...就是这样!

语法详细信息:sp_addlinkedserversp_addlinkedsrvlogin


4

在一个服务器上创建到另一个服务器的链接服务器定义(您需要SA来执行此操作),然后仅用4部分命名来引用它们(请参阅BOL)。


4

Server 2008:

在SSMS中连接到server1.DB1并尝试:

SELECT  * FROM
[server2].[DB2].[dbo].[table1]

正如其他人指出的那样,如果它不起作用,那是因为服务器未链接。

我收到错误:

在sys.servers中找不到服务器DB2。验证是否指定了正确的服务器名称。如有必要,执行存储过程sp_addlinkedserver将服务器添加到sys.servers。

要添加服务器:

参考:使用sp_addlinkedserver添加服务器链接:[1]:使用sp_addlinkedserver添加服务器

要查看sys.servers中的内容,只需查询它:

SELECT * FROM [sys].[servers]

3
 select * 
 from [ServerName(IP)].[DatabaseName].[dbo].[TableName]

2

正如@ Super9所讲的OPENDATASOURCE使用SQL Server身份验证和数据提供程序 SQLOLEDB 。我只是在这里发布一个表的代码段,该表位于运行该代码的当前服务器数据库中,而另一个表位于其他服务器“ 192.166.41.123”中

SELECT top 2 * from dbo.tblHamdoonSoft  tbl1 inner JOIN  
OpenDataSource('SQLOLEDB','Data Source=192.166.41.123;User ID=sa;Password=hamdoonsoft')
.[TestDatabase].[dbo].[tblHamdoonSoft1] tbl2 on tbl1.id = tbl2.id

0
sp_addlinkedserver('servername')

所以它应该像这样-

select * from table1
unionall
select * from [server1].[database].[dbo].[table1]

0

我知道这是一个老问题,但是我使用同义词。假设查询是在数据库服务器A中执行的,并在数据库服务器B中查找服务器A上不存在的表。然后在数据库A上添加一个同义词,该同义词从服务器B调用您的表。您的查询不必包括任何模式或不同的数据库名称,只需照常调用表名即可。

不需要链接服务器,因为每个同义词都可以链接。


1
那么,在这种情况下,什么是“同义词”?
奥斯卡·伯格格伦

它是一个数据库对象,它引用另一个数据库中的基础对象。这里更多的信息:docs.microsoft.com/en-us/sql/relational-databases/synonyms/...
尼克拉斯Henricson

太酷了,我不知道该功能。但是,您也声明他们避免了对链接服务器的需求,但是我看不到如何做。同义词本身似乎只是一个同义词,它本身并不包含任何特定的远程处理功能。在docs.microsoft.com/en-us/sql/t-sql/statements/…的示例B中,他们在从同义词引用它之前创建了链接服务器。
奥斯卡·伯格伦

没错,我假设数据库位于同一服务器环境中。当然,如果数据库彼此之间很遥远,则必须始终链接它们。没有其他方法可以使用数据库到数据库的关系进行访问。
尼古拉斯·亨里克森

0

服务器对象--->链接服务器--->新的链接服务器

在链接服务器中,输入其他服务器的服务器名称或IP地址,然后选择SQL Server。

现在连接然后使用

Select * from [server name or ip addresses ].databasename.dbo.tblname

0

添加链接服务器的简化解决方案

第一台服务器

EXEC sp_addlinkedserver @server='ip,port\instancename'

第二次登入

EXEC sp_addlinkedsrvlogin 'ip,port\instancename', 'false', NULL, 'remote_db_loginname', 'remote_db_pass'

从链接到本地​​数据库执行查询

INSERT INTO Tbl (Col1, Col2, Col3)
SELECT Col1, Col2, Col3
FROM [ip,port\instancename].[linkedDBName].[linkedTblSchema].[linkedTblName]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.