Seleccionar datos de dos servidores diferentes en SQL Server

363

¿Cómo puedo seleccionar datos en la misma consulta de dos bases de datos diferentes que están en dos servidores diferentes en SQL Server?

Eric
fuente
66
Las respuestas de Eric y Raging Bull son muy útiles. Pude usar esto para copiar volúmenes masivos de datos de DEV a PROD, reduciendo los tiempos desde 5 horas a 18 horas, hasta 17 segundos.
Chris Aldrich
@Eric, felicitaciones por editar una pregunta marginalmente ambigua y convertirla en una pregunta de 170 repeticiones :)
Eric Wu

Respuestas:

345

Lo que está buscando son servidores vinculados. Puede acceder a ellos en SSMS desde la siguiente ubicación en el árbol del Explorador de objetos:

Server Objects-->Linked Servers

o puede usar sp_addlinkedserver .

Solo tienes que configurar uno. Una vez que tenga eso, puede llamar a una tabla en el otro servidor de la siguiente manera:

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

Tenga en cuenta que el propietario no siempre es dboasí, así que asegúrese de reemplazarlo con el esquema que utilice.

Eric
fuente
13
¿podemos hacerlo sin servidores vinculados?
Steam
55
@Eric, ¿dónde están los objetos del servidor en SSMS?
Tsahi Asher
99
@TsahiAsher: cuando se conecta a un servidor, Server Objects es una carpeta en el árbol del Object Explorer.
Eric
2
Si no se conoce, también puede omitir el esquema para usar el predeterminado. Por ejemplo [OtherServerName].[OtherDB]..[OtherTable], es mejor incluirlo si se conoce.
Tom Bowers
92

Puede hacerlo usando el servidor vinculado.

Por lo general, los servidores vinculados se configuran para permitir que el Motor de base de datos ejecute una instrucción Transact-SQL que incluya tablas en otra instancia de SQL Server u otro producto de base de datos como Oracle. Muchos tipos de fuentes de datos OLE DB se pueden configurar como servidores vinculados, incluidos Microsoft Access y Excel.

Los servidores vinculados ofrecen las siguientes ventajas:

  • La capacidad de acceder a datos desde fuera de SQL Server.
  • La capacidad de emitir consultas distribuidas, actualizaciones, comandos y transacciones en fuentes de datos heterogéneas en toda la empresa.
  • La capacidad de abordar diversas fuentes de datos de manera similar.

Lea más sobre los servidores vinculados .

Siga estos pasos para crear un servidor vinculado:

  1. Objetos del servidor -> Servidores vinculados -> Nuevo servidor vinculado

  2. Proporcione el nombre del servidor remoto.

  3. Seleccione el tipo de servidor remoto (SQL Server u otro).

  4. Seleccione Seguridad -> Realizar utilizando este contexto de seguridad y proporcione el inicio de sesión y la contraseña del servidor remoto.

  5. Haga clic en Aceptar y ya está.

Aquí hay un tutorial simple para crear un servidor vinculado.

O

Puede agregar un servidor vinculado mediante la consulta.

Sintaxis:

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

Lea más sobre sp_addlinkedserver .

Debe crear un servidor vinculado solo una vez . Después de crear un servidor vinculado, podemos consultarlo de la siguiente manera:

select * from LinkedServerName.DatabaseName.OwnerName.TableName
Toro furioso
fuente
Nota: vea aquí cómo hacer que el nombre del servidor sea diferente al nombre de host / puerto.
Richard
1
Un pequeño consejo, aquí si tienes problemas con el sp_addlinkedserver. Cree el servidor en el cuadro de diálogo, asegúrese de que funciona, luego haga clic con el botón derecho en la conexión y seleccione la
secuencia de comandos
25
SELECT
        *
FROM
        [SERVER2NAME].[THEDB].[THEOWNER].[THETABLE]

También puede ver el uso de servidores vinculados. Los servidores vinculados también pueden ser otros tipos de fuentes de datos, como las plataformas de DB2. Este es un método para intentar acceder a DB2 desde una llamada SQL Server TSQL o Sproc ...

RSolberg
fuente
2
¿Este método funcionará todo el tiempo? ¿Cuáles son los escenarios donde podría fallar?
Steam
3
Confirmado que esto falla en mi entorno, el error dice que necesitaba usar addlinkedserver
gorlaz
1
¿Esto funciona para cualquier persona, sin usar un servidor vinculado?
Doug S
probado y el error recibido esCould 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
22

Consultar en 2 bases de datos diferentes es una consulta distribuida. Aquí hay una lista de algunas técnicas más los pros y los contras:

  1. Servidores vinculados: brindan acceso a una variedad más amplia de fuentes de datos que la replicación de SQL Server
  2. Servidores vinculados: conéctese con fuentes de datos que la replicación no admite o que requieren acceso ad hoc
  3. Servidores vinculados: funcionan mejor que OPENDATASOURCE o OPENROWSET
  4. Funciones OPENDATASOURCE y OPENROWSET : convenientes para recuperar datos de fuentes de datos de manera ad hoc. OPENROWSET también tiene instalaciones a GRANEL que pueden o no requerir un archivo de formato que podría ser fiddley
  5. OPENQUERY : no admite variables
  6. Todas son soluciones T-SQL. Relativamente fácil de implementar y configurar
  7. Todos dependen de la conexión entre la fuente y el destino, lo que puede afectar el rendimiento y la escalabilidad.
super9
fuente
OPENQUERY todavía requiere un servidor vinculado donde OPENDATASOURCE no lo hace
CJ
16

prueba esto:

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
Anna Karthi
fuente
16

Todas estas son buenas respuestas, pero esta falta y tiene sus propios usos poderosos. Posiblemente no se ajusta a lo que el OP quería, pero la pregunta era vaga y siento que otros pueden encontrar su camino aquí. Básicamente, puede usar 1 ventana para ejecutar simultáneamente una consulta en varios servidores, así es como:

En SSMS abrir Servidores registrados y crear un nuevo grupo de servidor bajo grupos locales del servidor .

En este grupo, cree un nuevo registro de servidor para cada servidor que desee consultar. Si los nombres de DB son diferentes, asegúrese de establecer un valor predeterminado para cada uno en las propiedades.

Ahora regrese al Grupo que creó en el primer paso, haga clic derecho y seleccione Nueva consulta. Se abrirá una nueva ventana de consulta y cualquier consulta que ejecute se ejecutará en cada servidor del grupo. Los resultados se presentan en un único conjunto de datos con un nombre de columna adicional que indica de qué servidor proviene el registro. Si usa la barra de estado, notará que el nombre del servidor se reemplaza por múltiple .

Pablo
fuente
2
Esto parece suponer que la consulta usa las mismas tablas en todas las bases de datos. (Lo cual está bien para tablas estándar como sys.tables pero no es probable para tablas personalizadas como dbo.mycustomers)
Dennis Jaheruddin
Dado que es "la misma consulta de dos bases de datos diferentes", es muy probable que tenga las mismas tablas. Pero sí, uso este método de manera rutinaria para un sistema de producción alojado en varios servidores y para consultar tablas MSDB.
Paul
Característica realmente genial en realidad. El inconveniente es que el esquema del conjunto de resultados debe coincidir, ya que ejecuta la consulta dos veces y las combina todas al mismo tiempo. Sería genial si pudiera hacer referencia a los servidores dentro del propio SQL, como puede hacerlo con los servidores vinculados, incluso si no pudiera UNIRSE al conjunto de resultados y los conjuntos tuvieran que construirse para ser evaluados por separado.
Kross
1
@Kross que más o menos podrías. Cree una tabla de #salida, haga lógica basada en @@ SERVERNAME y complete los datos en #salida, luego termínela con una selección sobre eso. Hice algo similar para consultar la información de registro de una combinación de máquinas SQL2000 y SQL2008R2 que tenían diferentes niveles / columnas de información, pero en lugar de @@ SERVERNAME estaba usando una variable de versión del servidor.
Paul
9

Tuve el mismo problema para conectar un SQL_server 2008 a un SQL_server 2016 alojado en un servidor remoto. Otras respuestas no me funcionaron directamente. Escribo mi solución ajustada aquí, ya que creo que puede ser útil para otra persona.

Una respuesta extendida para conexiones remotas de IP db:

Paso 1: enlace de servidores

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'

... donde SRV_NAMEes un nombre inventado. Lo usaremos para referirnos al servidor remoto de nuestras consultas. aaa.bbb.ccc.dddes la dirección IP del servidor remoto que aloja su base de datos SQLserver.

Paso 2: Ejecute sus consultas Por ejemplo:

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

...¡y eso es!

Detalles de sintaxis: sp_addlinkedserver y sp_addlinkedsrvlogin

MarcM
fuente
4

Creó una definición de servidor vinculado en un servidor al otro (necesita SA para hacer esto), luego simplemente haga referencia a ellos con nombres de 4 partes (vea BOL).

RBarryYoung
fuente
4

Servidor 2008:

Cuando esté en SSMS conectado al servidor1.DB1 e intente:

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

como otros señalaron, si no funciona es porque el servidor no está vinculado.

Me sale el error:

No se pudo encontrar el servidor DB2 en sys.servers. Verifique que se haya especificado el nombre correcto del servidor. Si es necesario, ejecute el procedimiento almacenado sp_addlinkedserver para agregar el servidor a sys.servers.

Para agregar el servidor:

referencia: Para agregar el servidor usando sp_addlinkedserver Enlace: [1]: Para agregar el servidor usando sp_addlinkedserver

Para ver lo que hay en su servidor sys.servers solo consulte:

SELECT * FROM [sys].[servers]
usuario3586922
fuente
3
 select * 
 from [ServerName(IP)].[DatabaseName].[dbo].[TableName]
Masum
fuente
2

Como @ Super9 contó sobre OPENDATASOURCE utilizando la autenticación de SQL Server con el proveedor de datos SQLOLEDB . Solo estoy publicando aquí un fragmento de código para una tabla en la base de datos del servidor actual donde se está ejecutando el código y otra en otro servidor '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
Muhammad Ashikuzzaman
fuente
0
sp_addlinkedserver('servername')

así que debería ir así:

select * from table1
unionall
select * from [server1].[database].[dbo].[table1]
ugio
fuente
0

Sé que esta es una vieja pregunta, pero uso sinónimos. Supuestamente, la consulta se ejecuta dentro del servidor de base de datos A, y busca una tabla en un servidor de base de datos B que no existe en el servidor A. Agregue luego un sinónimo en la base de datos A que llama a su tabla desde el servidor B. Su consulta no tiene que incluya esquemas o nombres de bases de datos diferentes, simplemente llame al nombre de la tabla de la forma habitual y funcionará.

No es necesario vincular servidores, ya que los sinónimos por ejemplo son una especie de enlace.

Niklas Henricson
fuente
1
Ahora bien, ¿qué es un "sinónimo" en este contexto?
Oskar Berggren
Es un objeto de base de datos que se refiere a un objeto base en otra base de datos. Más información aquí: docs.microsoft.com/en-us/sql/relational-databases/synimony/…
Niklas Henricson
Genial, no sabía sobre esa característica. Sin embargo, también indica que evitan la necesidad de un servidor vinculado, pero no veo cómo. Los sinónimos en sí mismos parecen ser solo eso, un sinónimo, y no contienen por sí mismos ninguna capacidad de comunicación remota específica. En el ejemplo B en docs.microsoft.com/en-us/sql/t-sql/statements/… , crean un servidor vinculado antes de hacer referencia a él desde un sinónimo.
Oskar Berggren
Es cierto, supuse que las bases de datos están en el mismo entorno de servidor. Por supuesto, siempre tendrá que vincular bases de datos si están alejadas entre sí. No hay otra forma de acceder con una relación de base de datos a base de datos.
Niklas Henricson
0

Objetos del servidor ---> servidor vinculado ---> nuevo servidor vinculado

En el servidor vinculado, escriba el nombre del servidor o la dirección IP para otro servidor y seleccione SQL Server In Security select (se debe hacer usando este contexto de seguridad) Escriba el nombre de usuario y la contraseña para otro servidor

Ahora conectado, luego use

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

Solución simplificada para agregar servidores vinculados

Primer servidor

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

Segundo inicio de sesión

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

Ejecutar consultas vinculadas a db local

INSERT INTO Tbl (Col1, Col2, Col3)
SELECT Col1, Col2, Col3
FROM [ip,port\instancename].[linkedDBName].[linkedTblSchema].[linkedTblName]
irfandar
fuente