ChatGPT解决这个技术问题 Extra ChatGPT

Selecting data from two different servers in SQL Server

How can I select data in the same query from two different databases that are on two different servers in SQL Server?

The answers from Eric and Raging Bull very handy. I was able to use this to copy mass volumes of data from DEV to PROD cutting down times from ranged from 5 hours to 18 hours, down to 17 seconds.
@Eric, kudos for editing a marginally ambiguous question and making it a 170-rep question :)

m
mark_h

What you are looking for are Linked Servers. You can get to them in SSMS from the following location in the tree of the Object Explorer:

Server Objects-->Linked Servers

or you can use sp_addlinkedserver.

You only have to set up one. Once you have that, you can call a table on the other server like so:

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

Note that the owner isn't always dbo, so make sure to replace it with whatever schema you use.


can we do it without linked servers ?
@Eric, Where is Server Objects in SSMS?
@TsahiAsher - When you connect to a server, Server Objects is a folder in the tree of the Object Explorer.
If not known, you can also omit the schema to use the default. E.g. [OtherServerName].[OtherDB]..[OtherTable] However it's best to include it if known.
Azure Server does not have Linked Servers folder
R
Raging Bull

You can do it using Linked Server.

Typically linked servers are configured to enable the Database Engine to execute a Transact-SQL statement that includes tables in another instance of SQL Server, or another database product such as Oracle. Many types OLE DB data sources can be configured as linked servers, including Microsoft Access and Excel.

Linked servers offer the following advantages:

The ability to access data from outside of SQL Server.

The ability to issue distributed queries, updates, commands, and transactions on heterogeneous data sources across the enterprise.

The ability to address diverse data sources similarly.

Read more about Linked Servers.

Follow these steps to create a Linked Server:

Server Objects -> Linked Servers -> New Linked Server Provide Remote Server Name. Select Remote Server Type (SQL Server or Other). Select Security -> Be made using this security context and provide login and password of remote server. Click OK and you are done !!

Here is a simple tutorial for creating a linked server.

OR

You can add linked server using query.

Syntax:

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

Read more about sp_addlinkedserver.

You have to create linked server only once. After creating linked server, we can query it as follows:

select * from LinkedServerName.DatabaseName.OwnerName.TableName

Note: see here for how to have server name be something other than the hostname/port.
Bit of a tip, here if you are having trouble with the sp_addlinkedserver. Create the server in the dialog - make sure it works - then right click the connection and select the scrip[t linked server AS create
R
RSolberg
SELECT
        *
FROM
        [SERVER2NAME].[THEDB].[THEOWNER].[THETABLE]

You can also look at using Linked Servers. Linked servers can be other types of data sources too such as DB2 platforms. This is one method for trying to access DB2 from a SQL Server TSQL or Sproc call...


will this method work all the time ? what are the scenarios where it could fail ?
Confirmed this fails in my env, error says I needed to use addlinkedserver
Does this work for anyone, without using a Linked Server?
tested and error received is 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.
T
Tim

Querying across 2 different databases is a distributed query. Here is a list of some techniques plus the pros and cons:

Linked servers: Provide access to a wider variety of data sources than SQL Server replication provides Linked servers: Connect with data sources that replication does not support or which require ad hoc access Linked servers: Perform better than OPENDATASOURCE or OPENROWSET OPENDATASOURCE and OPENROWSET functions: Convenient for retrieving data from data sources on an ad hoc basis. OPENROWSET has BULK facilities as well that may/may not require a format file which might be fiddley OPENQUERY: Doesn't support variables All are T-SQL solutions. Relatively easy to implement and set up All are dependent on connection between source and destionation which might affect performance and scalability


OPENQUERY still requires a linked server where as OPENDATASOURCE does not
P
Paul

These are all fine answers, but this one is missing and it has it's own powerful uses. Possibly it doesn't fit what the OP wanted, but the question was vague and I feel others may find their way here. Basically you can use 1 window to simultaneously run a query against multiple servers, here's how:

In SSMS open Registered Servers and create a New Server Group under Local Server Groups.

Under this group create New Server Registration for each server you wish to query. If the DB names are different ensure to set a default for each in the properties.

Now go back to the Group you created in the first step, right click and select New Query. A new query window will open and any query you run will be executed on each server in the group. The results are presented in a single data set with an extra column name indicating which server the record came from. If you use the status bar you will note the server name is replaced with multiple.


This seems to assume that the query uses the same tables on all databases. (Which is fine for standard tables like sys.tables but not likely for custom made tables like dbo.mycustomers)
Given it's "the same query from two different databases" it's highly likely to have the same tables. But yes I routinely use this method for a production system housed on several servers and for querying MSDB tables.
Really cool feature actually. The drawback is the schema of the result set must match, since it executes the query twice and merges them all at the same time. It would be great if you could reference the servers within the SQL itself, like you can with linked servers, even if you couldn't JOIN result set and the sets had to be constructed to be evaluated separately.
@Kross you sort of could. Create an #output table, do logic based on @@SERVERNAME and populate data into #output then end it with a select on that. I did a similar thing for querying Log info from a mix of SQL2000 and SQL2008R2 machines which had different levels/columns of information, but instead of @@SERVERNAME I was using a server version variable.
This is a lovely Answer, and a year later someone else was looking just for this. Thank you
R
Radim Köhler

try this:

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

M
MarcM

I had the same issue to connect an SQL_server 2008 to an SQL_server 2016 hosted in a remote server. Other answers didn't worked for me straightforward. I write my tweaked solution here as I think it may be useful for someone else.

An extended answer for remote IP db connections:

Step 1: link servers

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'

...where SRV_NAME is an invented name. We will use it to refer to the remote server from our queries. aaa.bbb.ccc.ddd is the ip address of the remote server hosting your SQLserver DB.

Step 2: Run your queries For instance:

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

...and that's it!

Syntax details: sp_addlinkedserver and sp_addlinkedsrvlogin


C
ChrisM

Server 2008:

When in SSMS connected to server1.DB1 and try:

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

as others noted, if it doesn't work it's because the server isn't linked.

I get the error:

Could not find server DB2 in sys.servers. Verify that the correct server name was specified. If necessary, execute stored procedure sp_addlinkedserver to add the server to sys.servers.

To add the server:

reference: To add server using sp_addlinkedserver Link: [1]: To add server using sp_addlinkedserver

To see what is in your sys.servers just query it:

SELECT * FROM [sys].[servers]

i
irfandar

Simplified solution for adding linked servers

First server

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

Second Login

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

Execute queries from linked to local db

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

R
RBarryYoung

Created a Linked Server definition in one server to the other (you need SA to do this), then just reference them with 4-part naming (see BOL).


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

M
Muhammad Ashikuzzaman

As @Super9 told about OPENDATASOURCE using SQL Server Authentication with data provider SQLOLEDB . I am just posting here a code snippet for one table is in the current sever database where the code is running and another in other server '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

N
Niklas Henricson

I know this is an old question but I use synonyms. Supposedly the query is executed within database server A, and looks for a table in a database server B that does not exist on server A. Add then a synonym on A database that calls your table from server B. Your query doesn't have to include any schemas, or different database names, just call the table name per usual and it will work.

There's no need to link servers as synonyms per say are sort of linking.


Now then, what is a "synonym" in this context?
It's a database object that refers to a base object in another database. More info here: docs.microsoft.com/en-us/sql/relational-databases/synonyms/…
Cool, I did not know about that feature. However, you also state they avoid the need for a linked server, but I fail to see how. Synonyms itself appear to be just that, a synonym, and not itself contain any specific remoting ability. In example B at docs.microsoft.com/en-us/sql/t-sql/statements/…, they create a linked server before referencing it from a synonym.
True, I assumed the databases are in the same server environment. Of course you'll always have to link databases if they're remote from each other. There's no other way to access with a database-to-database relationship.
A
Andrius Naruševičius
sp_addlinkedserver('servername')

so its should go like this -

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

C
ChrisM

Server Objects---> linked server ---> new linked server

In linked server write server name or IP address for other server and choose SQL Server In Security select (be made using this security context ) Write login and password for other server

Now connected then use

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