Selecionando dados de dois servidores diferentes no SQL Server

363

Como posso selecionar dados na mesma consulta de dois bancos de dados diferentes que estão em dois servidores diferentes no SQL Server?

Eric
fonte
6
As respostas de Eric e Raging Bull são muito úteis. Consegui usar isso para copiar grandes volumes de dados do DEV para o PROD, reduzindo o tempo entre 5 e 18 horas e até 17 segundos.
Chris Aldrich
@Eric, elogios para a edição de uma questão marginal ambígua e tornando-se uma questão de 170 rep :)
Eric Wu

Respostas:

345

O que você está procurando são servidores vinculados. Você pode acessá-los no SSMS no seguinte local na árvore do Pesquisador de Objetos:

Server Objects-->Linked Servers

ou você pode usar sp_addlinkedserver .

Você só precisa configurar um. Depois disso, você pode chamar uma tabela no outro servidor da seguinte maneira:

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

Observe que o proprietário nem sempre é dbo, portanto, substitua-o por qualquer esquema que você use.

Eric
fonte
13
podemos fazer isso sem servidores vinculados?
Steam
5
@ Eric, onde estão os objetos de servidor no SSMS?
Tsahi Asher 15/09/14
9
@TsahiAsher - Quando você se conecta a um servidor, o Server Objects é uma pasta na árvore do Pesquisador de Objetos.
Eric
2
Se não for conhecido, você também pode omitir o esquema para usar o padrão. Por exemplo, no [OtherServerName].[OtherDB]..[OtherTable]entanto, é melhor incluí-lo, se conhecido.
Tom Bowers
92

Você pode fazer isso usando o servidor vinculado.

Normalmente, os servidores vinculados são configurados para permitir que o Mecanismo de Banco de Dados execute uma instrução Transact-SQL que inclua tabelas em outra instância do SQL Server ou em outro produto de banco de dados, como Oracle. Muitos tipos de fontes de dados OLE DB podem ser configurados como servidores vinculados, incluindo Microsoft Access e Excel.

Servidores vinculados oferecem as seguintes vantagens:

  • A capacidade de acessar dados de fora do SQL Server.
  • A capacidade de emitir consultas distribuídas, atualizações, comandos e transações em fontes de dados heterogêneas em toda a empresa.
  • A capacidade de abordar diversas fontes de dados da mesma forma.

Leia mais sobre servidores vinculados .

Siga estas etapas para criar um servidor vinculado:

  1. Objetos de servidor -> servidores vinculados -> novo servidor vinculado

  2. Forneça o nome do servidor remoto.

  3. Selecione Tipo de servidor remoto (SQL Server ou Outro).

  4. Selecione Segurança -> Ser criado usando este contexto de segurança e forneça login e senha do servidor remoto.

  5. Clique em OK e pronto!

Aqui está um tutorial simples para criar um servidor vinculado.

OU

Você pode adicionar um servidor vinculado usando a consulta.

Sintaxe:

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

Leia mais sobre sp_addlinkedserver .

Você precisa criar um servidor vinculado apenas uma vez . Após criar o servidor vinculado, podemos consultá-lo da seguinte forma:

select * from LinkedServerName.DatabaseName.OwnerName.TableName
Touro bravo
fonte
Nota: veja aqui como obter o nome do servidor diferente de hostname / porta.
Richard
11
Uma dica, aqui, se você estiver tendo problemas com o sp_addlinkedserver. Crie o servidor na caixa de diálogo - verifique se ele funciona - e clique com o botão direito do mouse na conexão e selecione o servidor de script [t vinculado como criar
Richard Housham 19/16
25
SELECT
        *
FROM
        [SERVER2NAME].[THEDB].[THEOWNER].[THETABLE]

Você também pode examinar o uso de servidores vinculados. Servidores vinculados também podem ser outros tipos de fontes de dados, como plataformas DB2. Este é um método para tentar acessar o DB2 a partir de uma chamada SQL Server TSQL ou Sproc ...

RSolberg
fonte
2
esse método funcionará o tempo todo? Quais são os cenários em que isso pode falhar?
vapor
3
Confirmou esta falha no meu env, erro diz que eu precisava usar addlinkedserver
gorlaz
11
Isso funciona para qualquer pessoa, sem usar um servidor vinculado?
Doug S
testado e o erro recebido é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
22

Consultar dois bancos de dados diferentes é uma consulta distribuída. Aqui está uma lista de algumas técnicas, além dos prós e contras:

  1. Servidores vinculados: forneça acesso a uma variedade maior de fontes de dados do que a replicação do SQL Server fornece
  2. Servidores vinculados: conecte-se a fontes de dados que a replicação não oferece suporte ou que exijam acesso ad hoc
  3. Servidores vinculados: desempenho melhor que OPENDATASOURCE ou OPENROWSET
  4. Funções OPENDATASOURCE e OPENROWSET : Conveniente para recuperar dados de fontes de dados em uma base ad hoc. O OPENROWSET também possui recursos GRANDES, que podem ou não exigir um arquivo de formato que pode ser complicado
  5. OPENQUERY : não suporta variáveis
  6. Todos são soluções T-SQL. Relativamente fácil de implementar e configurar
  7. Todos dependem da conexão entre origem e destino, o que pode afetar o desempenho e a escalabilidade
super9
fonte
OPENQUERY ainda requer um servidor vinculado onde OPENDATASOURCE não
CJ
16

tente isto:

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
fonte
16

Todas essas são boas respostas, mas essa está faltando e tem seus próprios usos poderosos. Possivelmente, não se encaixa no que o OP queria, mas a pergunta era vaga e acho que outras pessoas podem encontrar o caminho até aqui. Basicamente, você pode usar 1 janela para executar simultaneamente uma consulta em vários servidores. Veja como:

Em SSMS abrir Servidores Registrados e criar um novo grupo de servidor sob grupos locais do servidor .

Nesse grupo, crie Novo Registro de Servidor para cada servidor que você deseja consultar. Se os nomes do banco de dados forem diferentes, defina um padrão para cada um nas propriedades.

Agora volte ao grupo que você criou na primeira etapa, clique com o botão direito do mouse e selecione Nova consulta. Uma nova janela de consulta será aberta e qualquer consulta que você executar será executada em cada servidor do grupo. Os resultados são apresentados em um único conjunto de dados com um nome de coluna extra, indicando de qual servidor o registro veio. Se você usar a barra de status, notará que o nome do servidor é substituído por vários .

Paulo
fonte
2
Isso parece assumir que a consulta usa as mesmas tabelas em todos os bancos de dados. (O que é bom para tabelas padrão como sys.tables, mas não provável para tabelas personalizadas feitas como dbo.mycustomers)
Dennis Jaheruddin
Dado que é "a mesma consulta de dois bancos de dados diferentes", é altamente provável que tenha as mesmas tabelas. Mas sim, eu rotineiramente uso esse método para um sistema de produção hospedado em vários servidores e para consultar tabelas do MSDB.
Paul
Recurso realmente legal, na verdade. A desvantagem é que o esquema do conjunto de resultados deve corresponder, pois ele executa a consulta duas vezes e mescla todas elas ao mesmo tempo. Seria ótimo se você pudesse fazer referência aos servidores dentro do próprio SQL, como você pode fazer com os servidores vinculados, mesmo que você não pudesse JOIN conjunto de resultados e os conjuntos precisassem ser construídos para serem avaliados separadamente.
Kross
11
@ Kross você meio que poderia. Crie uma tabela #output, faça lógica com base em @@ SERVERNAME e preencha os dados em #output e termine-os com uma seleção. Fiz uma coisa semelhante ao consultar informações de log de uma combinação de máquinas SQL2000 e SQL2008R2 que tinham diferentes níveis / colunas de informações, mas, em vez de @@ SERVERNAME, eu estava usando uma variável de versão do servidor.
Paul
9

Eu tive o mesmo problema para conectar um SQL_server 2008 a um SQL_server 2016 hospedado em um servidor remoto. Outras respostas não funcionaram para mim diretamente. Escrevo aqui minha solução aprimorada, pois acho que pode ser útil para outra pessoa.

Uma resposta estendida para conexões IP db remotas:

Etapa 1: vincular 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'

... onde SRV_NAMEé um nome inventado. Nós o usaremos para nos referir ao servidor remoto a partir de nossas consultas. aaa.bbb.ccc.dddé o endereço IP do servidor remoto que hospeda seu banco de dados SQLserver.

Etapa 2: execute suas consultas Por exemplo:

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

...e é isso!

Detalhes da sintaxe: sp_addlinkedserver e sp_addlinkedsrvlogin

MarcM
fonte
4

Criou uma definição de servidor vinculado em um servidor para outro (você precisa do SA para fazer isso) e, em seguida, apenas faça referência a elas com nomes de quatro partes (consulte BOL).

RBarryYoung
fonte
4

Server 2008:

Quando estiver no SSMS conectado ao server1.DB1 e tente:

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

como outros observaram, se não funcionar, é porque o servidor não está vinculado.

Eu recebo o erro:

Não foi possível encontrar o servidor DB2 em sys.servers. Verifique se o nome do servidor correto foi especificado. Se necessário, execute o procedimento armazenado sp_addlinkedserver para adicionar o servidor ao sys.servers.

Para adicionar o servidor:

referência: Para adicionar servidor usando sp_addlinkedserver Link: [1]: Para adicionar servidor usando sp_addlinkedserver

Para ver o que está em seus sys.servers, basta consultá-lo:

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

Como @ Super9 falou sobre o OPENDATASOURCE usando a Autenticação do SQL Server com o provedor de dados SQLOLEDB . Estou apenas postando aqui um trecho de código para uma tabela no banco de dados atual do servidor em que o código está sendo executado e outra no outro 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
fonte
0
sp_addlinkedserver('servername')

então deve ser assim -

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

Sei que essa é uma pergunta antiga, mas uso sinônimos. Supostamente, a consulta é executada no servidor de banco de dados A e procura uma tabela em um servidor de banco de dados B que não existe no servidor A. Adicione um sinônimo no banco de dados A que chama sua tabela do servidor B. Sua consulta não precisa ser inclua esquemas ou nomes diferentes de bancos de dados, basta chamar o nome da tabela normalmente e ele funcionará.

Não há necessidade de vincular servidores, pois os sinônimos, por assim dizer, são uma espécie de vinculação.

Niklas Henricson
fonte
11
Agora, então, o que é um "sinônimo" neste contexto?
Oskar Berggren
É um objeto de banco de dados que se refere a um objeto base em outro banco de dados. Mais informações aqui: docs.microsoft.com/en-us/sql/relational-databases/synonym/…
Niklas Henricson
Legal, eu não sabia sobre esse recurso. No entanto, você também afirma que eles evitam a necessidade de um servidor vinculado, mas não consigo entender como. O próprio sinônimos parece ser apenas isso, um sinônimo, e não ele próprio, contém qualquer capacidade remota específica. No exemplo B, em docs.microsoft.com/en-us/sql/t-sql/statements/… , eles criam um servidor vinculado antes de fazer referência a um sinônimo.
Oskar Berggren
É verdade que eu assumi que os bancos de dados estão no mesmo ambiente de servidor. É claro que você sempre precisará vincular bancos de dados se eles estiverem distantes um do outro. Não há outra maneira de acessar com um relacionamento de banco de dados para banco de dados.
Niklas Henricson
0

Objetos de servidor ---> servidor vinculado ---> novo servidor vinculado

No servidor vinculado, escreva o nome do servidor ou o endereço IP de outro servidor e escolha SQL Server In Security.

Agora conectado e use

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

Solução simplificada para adicionar servidores vinculados

Primeiro servidor

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

Segundo Login

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

Executar consultas vinculadas ao banco de dados local

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