121

While in Management Studio, I am trying to run a query/do a join between two linked servers. Is this a correct syntax using linked db servers:

select foo.id 
from databaseserver1.db1.table1 foo, 
     databaseserver2.db1.table1 bar 
where foo.name=bar.name

Basically, do you just preface the db server name to the db.table ?

0

17 Answers 17

228

The format should probably be:

<server>.<database>.<schema>.<table>

For example: DatabaseServer1.db1.dbo.table1


Update: I know this is an old question and the answer I have is correct; however, I think any one else stumbling upon this should know a few things.

Namely, when querying against a linked server in a join situation the ENTIRE table from the linked server will likely be downloaded to the server the query is executing from in order to do the join operation. In the OP's case, both table1 from DB1 and table1 from DB2 will be transferred in their entirety to the server executing the query, presumably named DB3.

If you have large tables, this may result in an operation that takes a long time to execute. After all it is now constrained by network traffic speeds which is orders of magnitude slower than memory or even disk transfer speeds.

If possible, perform a single query against the remote server, without joining to a local table, to pull the data you need into a temp table. Then query off of that.

If that's not possible then you need to look at the various things that would cause SQL server to have to load the entire table locally. For example using GETDATE() or even certain joins. Others performance killers include not giving appropriate rights.

See http://thomaslarock.com/2013/05/top-3-performance-killers-for-linked-server-queries/ for some more info.

Sign up to request clarification or add additional context in comments.

10 Comments

if the databaseserver name has a hyphen, need to surround it with square brackets
@bmw0128: Better yet, use double quotes: it's supported by almost every platform, unlike Microsoft's square brackets.
You also need to use the square brackets or double quotes when the database server name has a period in it.
If you're uncertain about any of the qualifiers, drill down to a table in a Linked Server in SSMS Object Explorer, right-click, and Script Table as, SELECT To, and New Query Editor Window. The resulting SELECT statement will include the correct, fully-qualified path to the table. I had a mystery database qualifier in working with Sybase and this gave me the correct name.
Just to write down something no explicitly written anywhere: <server> refers to the linked server name.
|
53
SELECT * FROM OPENQUERY([SERVER_NAME], 'SELECT * FROM DATABASE_NAME..TABLENAME')

This may help you.

3 Comments

Upvoted. This works when you're linking MySQL to MS SQL.
In other words, this is creating a pass-through query. Keep in mind that the query statement has to be written in the native SQL for the server. Syntax for Oracle being different than Teradata different than SQL Server etc.
It's my understanding this is a "pass-through query" that passes SQL to the other server; and while useful for accessing other vendors' databases, it's best to use a "native" query between MS-Sql-Server instances when both are MS-SQL-Server (and maybe compatible versions). For one, quote escaping complications are avoided. Is there a performance benefit of native mode?
18

For those having trouble with these other answers , try OPENQUERY

Example:

 SELECT * FROM OPENQUERY([LinkedServer], 'select * from [DBName].[schema].[tablename]') 

2 Comments

Works for SQL Server
This is the only solution which works for me. Quick translation (may be helpful to some): SELECT * INTO NEW_DB.dbo.tblCopy FROM OLD_DB.dbo.tblData forms to SELECT * INTO NEW_DB.dbo.tblCopy FROM OPENQUERY([server], 'select * from OLD_DB.dbo.tblData')
11

If you still find issue with <server>.<database>.<schema>.<table>

Enclose server name in []

1 Comment

Careful: I executed a create table from select using [], and instead of being created on the Linked Server, the table was created locally with a name like dbo.databaseserver1.db1.dbo.table1
10

You need to specify the schema/owner (dbo by default) as part of the reference. Also, it would be preferable to use the newer (ANSI-92) join style.

select foo.id 
    from databaseserver1.db1.dbo.table1 foo
        inner join databaseserver2.db1.dbo.table1 bar 
            on foo.name = bar.name

3 Comments

the inner join syntax is preferable to the implicit joins?
@bmw0128: Yes, for several reasons. IMHO, the most important is that it is way too easy to accidentally write a cross product join when you have your tables and joins in two different place.
Note that the 4-dotted-parts DOES NOT WORK for some non-SQL-Server linked servers. It can raise an error like ... An invalid schema or catalog was specified for the provider "MSDASQL" for linked server "MyLinkedServer".
8
select * from [Server].[database].[schema].[tablename] 

This is the correct way to call. Be sure to verify that the servers are linked before executing the query!

To check for linked servers call:

EXEC sys.sp_linkedservers 

1 Comment

This DOES NOT WORK for some non-SQL-Server linked servers. It raises error like ... An invalid schema or catalog was specified for the provider "MSDASQL" for linked server "MyLinkedServer".
8

right click on a table and click script table as select

enter image description here

3 Comments

That is not what the OP asked
this shows how to get the correct syntax for select query on a linked table. the result is like of seans answer
@ShimonDoodkin, an excellent example of don't give me a fish, but teach me how to fish
4
select name from drsql01.test.dbo.employee
  • drslq01 is servernmae --linked serer
  • test is database name
  • dbo is schema -default schema
  • employee is table name

I hope it helps to understand, how to execute query for linked server

Comments

3

Usually direct queries should not be used in case of linked server because it heavily use temp database of SQL server. At first step data is retrieved into temp DB then filtering occur. There are many threads about this. It is better to use open OPENQUERY because it passes SQL to the source linked server and then it return filtered results e.g.

SELECT *
FROM OPENQUERY(Linked_Server_Name , 'select * from TableName where ID = 500')

4 Comments

This answer doesn't include a database name
I do have provided database information while creating the linked server. For detail you can see below MSDN link: msdn.microsoft.com/en-us/library/ff772782(v=sql.110).aspx
What can I do if my linked server require authentication and I'm just trying to querying from my PHP application using PDO ?
How would you perform a join from database 1, to database on linked server, using this approach?
2

For what it's worth, I found the following syntax to work the best:

SELECT * FROM [LINKED_SERVER]...[TABLE]

I couldn't get the recommendations of others to work, using the database name. Additionally, this data source has no schema.

Comments

2

In sql-server(local) there are two ways to query data from a linked server(remote).

Distributed query (four part notation):

  1. Might not work with all remote servers. If your remote server is MySQL then distributed query will not work.
  2. Filters and joins might not work efficiently. If you have a simple query with WHERE clause, sql-server(local) might first fetch entire table from the remote server and then apply the WHERE clause locally. In case of large tables this is very inefficient since a lot of data will be moved from remote to local. However this is not always the case. If the local server has access to remote server's table statistics then it might be as efficient as using openquery More details
  3. On the positive side T-SQL syntax will work.
SELECT * FROM [SERVER_NAME].[DATABASE_NAME].[SCHEMA_NAME].[TABLE_NAME] 

OPENQUERY

  1. This is basically a pass-through. The query is fully processed on the remote server thus will make use of index or any optimization on the remote server. Effectively reducing the amount of data transferred from the remote to local sql-server.
  2. Minor drawback of this approach is that T-SQL syntax will not work if the remote server is anything other than sql-server.
SELECT * FROM OPENQUERY([SERVER_NAME], 'SELECT * FROM DATABASE_NAME.SCHEMA_NAME.TABLENAME')

Overall OPENQUERY seems like a much better option to use in majority of the cases.

Comments

1

I have done to find out the data type in the table at link_server using openquery and the results were successful.

SELECT * FROM OPENQUERY (LINKSERVERNAME, '
SELECT DATA_TYPE, COLUMN_NAME
FROM [DATABASENAME].INFORMATION_SCHEMA.COLUMNS
WHERE 
     TABLE_NAME  =''TABLENAME''
')

Its work for me

Comments

0

Following Query is work best.

Try this Query:

SELECT * FROM OPENQUERY([LINKED_SERVER_NAME], 'SELECT * FROM [DATABASE_NAME].[SCHEMA].[TABLE_NAME]')

It Very helps to link MySQL to MS SQL

Comments

0

PostgreSQL:

  1. You must provide a database name in the Data Source DSN.
  2. Run Management Studio as Administrator
  3. You must omit the DBName from the query:

    SELECT * FROM OPENQUERY([LinkedServer], 'select * from schema."tablename"')

Comments

0

For MariaDB (and so probably MySQL), attempting to specify the schema using the three-dot syntax did not work, resulting in the error "invalid use of schema or catalog". The following solution worked:

  1. In SSMS, go to Server Objects > Linked Servers > Providers > MSDASQL
  2. Ensure that "Dynamic parameter", "Level zero only", and "Allow inprocess" are all checked

You can then query any schema and table using the following syntax:

SELECT TOP 10 *
FROM LinkedServerName...[SchemaName.TableName]

Source: SELECT * FROM MySQL Linked Server using SQL Server without OpenQuery

Comments

0

Have you tried adding " around the first name?

like:

select foo.id 
from "databaseserver1".db1.table1 foo, 
     "databaseserver2".db1.table1 bar 
where foo.name=bar.name

Comments

0

I'm connecting to a MySQL linked server. Turned out that the schema name is "public", which in T-SQL is a reserved word. In SSMS, it's seen as:

HostServerName\DatabaseName > Server Objects > Linked Servers > LinkedServerName > Catalogs > LinkedServerName > Tables > public.TableName

Once I surrounded each section in square brackets, that worked.

Select * FROM [LinkedServerName].[LinkedServerName].[public].[TableName]

If I tried to group the entire tablename together ("[public.TableName]"), that failed. The keyword "public" had to be separated by itself. The other components worked either with or without the brackets, since they didn't involve punctuation, spaces, keywords, or anything else to cause problems.

What was frustrating was that Script Table As > Select To failed, either to a window or to the clipboard, with an error of "Enumerate columns failed", without showing the specific failed command or the failed column. When I use a generic Select like the one above, that works - once I get around the reserved keyword.

Some may consider this a dead thread, but it was a top Google result. Maybe this will help someone else with the same issue.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.