Linked Servers

Query remote SQL Server and non-SQL Server databases as if they were local

Downloads
8992.zip

Linked servers are often-untapped resources that let you use distributed queries to query any server as if it were local. Distributed queries let you keep your inventory data in a DB2 database, for example, and your accounting data in a SQL Server database and query both sets of data as if they were in the same database, eliminating the cost and hassle of merging the two systems. SQL Server lets you execute such queries on any OLE DB-compliant data source. This article shows you how to set up, query, and gather meta data about linked servers.

About Linked Servers

Linked servers are descendants of remote servers, which you can use to execute replication stored procedures in SQL Server. However, Microsoft recommends that you use linked servers instead of remote servers in SQL Server 2000 or SQL Server 7.0 because linked servers have much more functionality, such as the ability to run ad hoc queries. With linked servers, you begin by establishing a connection in SQL Server to a compatible remote OLE DB provider. SQL Server clients connect to the linked server, then SQL Server connects to the remote provider on the client's behalf, as Figure 1 shows. The linked server acts as a middleman, taking an order from the consumer, passing it to the source, then passing it back to the consumer.

Linked servers are especially useful when configuring the OLE DB data source on each client computer is too time-consuming. In addition, stabilizing connections to other types of servers, such as DB2, can be tricky; linked servers minimize this complexity because you need to configure the connection only once. Clients need to connect only to the standard SQL Server provider; they don't need to have an OLE DB provider for DB2, for example, on their workstations.

Linked servers are also the core technology in SQL Server 2000 distributed partitioned views. In a distributed partitioned view, you can make several uniformly distributed tables appear as one table and distribute the load of large queries among many servers. (For more information about distributed partitioned views, see Kalen Delaney and Itzik Ben-Gan, "Distributed Partitioned Views.") To make this new SQL Server 2000 feature work, however, you need to inform each node of the other nodes' existence by adding a linked server for each participating node in each SQL Server system.

Setting Up a Linked Server

Most of the following examples show you how to link one SQL Server machine to another. I also explain briefly how to connect to DB2 and Oracle. Linked servers are new beginning in SQL Server 7.0, so avoid bugs by installing the latest service pack. If you haven't already done so, I recommend that you install Service Pack 2 (SP2), which contains quite a few fixes for linked servers. Some of the most dangerous bugs include access violation (AV) errors that occur when you use linked servers.

You can add a linked server through Enterprise Manager. From the Security menu, right-click the linked server icon and select New Linked Server. Or you can script the process in T-SQL by using the sp_addlinkedserver stored procedure:

sp_addlinkedserver \[@server =\] '<em>logical name of server</em>'
\[, \[@srvproduct =\] '<em>product_name</em>'\]
\[, \[@provider =\] '<em>provider_name</em>'\]
\[, \[@datasrc =\] '<em>data_source</em>'\]
\[, \[@location =\] '<em>location</em>'\]
\[, \[@provstr =\] '<em>provider_string</em>'\]
\[, \[@catalog =\] '<em>catalog</em>'\]

Table 1 describes each of these parameters, which also exist in the Enterprise Manager screens. The following sp_addlinkedserver example adds a linked server named LINKEDSERVER, which connects to a SQL Server named BKNIGHT:

EXEC sp_addlinkedserver
   @server=LINKEDSERVER,
   @srvproduct = 'SQLServer OLEDB Provider',
   @provider = 'SQLOLEDB',
   @datasrc = 'BKNIGHT'

The @provider parameter is the name of the OLE DB provider that you want to use. SQL Server's OLE DB name is SQLOLEDB. Table 2 lists the core OLE DB providers' names.

After you've added the linked server, you need to set the security method it will use to connect to the remote data source. You set the security method by using the sp_addlinkedsrvlogin stored procedure:

sp_addlinkedsrvlogin \[@rmtsrvname =\] '<em>rmtsrvname</em>'
\[,\[@useself =\] '<em>useself</em>'\]
\[,\[@locallogin =\] '<em>locallogin</em>'\]
\[,\[@rmtuser =\] '<em>rmtuser</em>'\]
\[,\[@rmtpassword =\] '<em>rmtpassword</em>'\]

Table 3 describes sp_addlinkedsrvlogin's parameters.

Windows NT integrated security becomes especially useful here. If you configure the security correctly, users can log in to the SQL Server machine with their NT logins, and the linked server will pass the remote server a mapped standard SQL Server login with the appropriate permissions. You can't pass NT credentials from the client workstation to the linked server then to the remote server. To circumvent this barrier, map a standard account on the remote server with an NT account on the local server. This workaround is called a double hop. Failure to map the account this way will result in the following error:

<em>Server: Msg 18456, Level 14, State 1, Line 1 Login failed for user '\'</em>

For more information about double hopping and this error, see the Microsoft article "PRB: Message 18456 from a Distributed Query" (http://support.microsoft.com/support/kb/articles/q238/4/77.asp).

The following example sets the SQL Server security for the linked server, using an account named user account to connect to the remote SQL Server:

EXEC sp_addlinkedsrvlogin
  @rmtsrvname='LINKEDSERVER',
  @useself='false',
  @rmtuser='useraccount',
  @rmtpassword='userspassword'

You can use the sp_serveroption stored procedure to set additional access and optimization options. The most valuable of these options is the collation compatible option. When you select this option (by using the sp_serveroption stored procedure or by selecting the appropriate check box in Enterprise Manager in the linked server's configuration dialog box), SQL Server assumes that the source and destination servers are both operating on the same collation--a particular combination of sort order and language. The collation compatible option tells SQL Server not to pull the query back to parse the ORDER BY clause, which would substantially slow performance, but to pass the query to the provider and let the provider execute the query. The data access option lets you access the data on the linked server. Finally, the RPC and RPC out options allow remote procedure calls in and out of your linked server.

You can use T-SQL to set sp_serveroption options. The following code sets the collation compatible option:

EXEC sp_serveroption 'LINKEDSERVER', 'collation compatible', 'true'

You can modify this code to set the data access option and the RPC and RPC out options.

A frustrating thing about linked servers is that you can't easily update their settings after you create links to them. You can, however, change the options and change the security configuration. The easiest way to update your linked server after creation is to drop it and recreate it. Therefore, you should always save the scripts that you use to create linked servers so that you can quickly recreate them by running the scripts in Query Analyzer.

Querying a Linked Server

After you've added a linked server, you can query it using one of three methods. The easiest method, which works well with other SQL Server systems, is to use a four-part qualifier in your queries:

SELECT * FROM LINKEDSERVER.NORTHWIND.DBO.CATEGORIES

Be aware, however, that this method of querying your linked server doesn't work well with some heterogeneous data sources, such as DB2. Queries of most heterogeneous data sources perform better with the OPENQUERY command, which we'll explore in a moment.

With a linked server, you can join tables the same way you can on a local server. The following example supposes that you have inventory information on one server and an order system on another:

SELECT lnw.CompanyName, rnw.OrderID, rnw.OrderDate, rnw.Freight FROM   LINKEDSERVER.Northwind.dbo.orders rnw, Northwind..Customers lnw WHERE  lnw.CustomerID = rnw.CustomerID AND    rnw.shipcountry = 'USA' AND    rnw.OrderDate > ' 04 / 22 / 1998'

When Query Optimizer parses these queries, it reads the capabilities of the OLE DB provider before executing.

The UNION ALL command lets you use linked server technology to make multiple databases look like one database. With UNION ALL, you can create a distributed partitioned view. The following query gathers all categories from two SQL Servers and merges the returned results into one recordset:

SELECT * FROM LINKEDSERVER.NORTHWIND.DBO.CATEGORIES UNION ALL SELECT * FROM Northwind..Categories

This approach is useful when you have data that is partitioned on separate servers by date, for example, and you want to generate a unified report of all servers.

The second way to query a linked server is to use the OPENQUERY command. This command is perfect for heterogeneous databases because it executes the requested query on the remote system, not on the SQL Server system that hosts the linked server. I've had many queries that wouldn't work with the four-part identifier but work fine with the OPENQUERY command. When you use the OPENQUERY command, you instruct SQL Server to select all records that the query specifies between the quotation marks:

SELECT * FROM OPENQUERY(LINKEDSERVER, "SELECT * FROM northwind..Categories where CategoryName Like 'Sea%'")

The first required piece of syntax is the linked server name, followed by the query. Notice that you need to use single quotes around the conditional piece of the query.

The third way to query a remote provider is to use the OPENROWSET command, which doesn't require that you have a linked server set up beforehand. This command uses linked server technology but creates the link at runtime, letting you dynamically set up the server you want to connect to. The OPENROWSET command operates the same as the OPENQUERY command: It executes all queries on the remote server. The example query in Listing 1 uses the OPENROWSET command. Listing 1's example code also shows that you can use the OPENROWSET (or OPENQUERY) command to perform joins.

Although OPENROWSET gives you additional flexibility and power to dynamically create connections, I don't recommend using this command unless you can absolutely justify a need. Having a centralized location where you can configure your linked server is much more convenient than having to recompile your code every time you make a connection change.

Gathering Meta Data

The stored procedure I use most for gathering linked server data is sp_linkedservers. This stored procedure tells you how many linked servers are configured and gives you information about them. The procedure is handy if you have obscure names for your linked servers because remembering such names can be difficult. If you haven't established a linked server, you'll see only one result: the local server's information.

You can also request a list of databases that are on your linked servers by using the sp_catalogs stored procedure. This stored procedure uses the @server_name variable, which is the name of the linked server you're querying:

sp_catalogs @server_name = 'LINKEDSERVER'

You can request a list of tables in a database by using the sp_tables_ex stored procedure:

EXEC sp_tables_ex @table_server = 'LINKEDSERVER', @table_catalog='northwind', @table_schema='dbo', @table_name='Suppliers'

Using some of the nonrequired parameters, such as @table_catalog and @table_name, is important when you want a list of only a subset of the database's tables. If you don't use the @table_name parameter, for example, the stored procedure will return every table in the database. If you don't use the @table_catalog parameter, the stored procedure will return the default database's tables only.

You can use several other stored procedures to obtain meta data about your linked server's tables and indexes. For a complete list of other stored procedures, see SQL Server Books Online (BOL).

Many companies can't or don't plan to upgrade their non-SQL Server infrastructures to SQL Server either because of the cost or because of the complexity. In these cases, linked servers let you build applications that take advantage of SQL Server's features but still access your legacy data. Linked servers also let you partition your data geographically or logically, dividing the load among the various servers.

Discuss this Article 9

Dmitry (not verified)
on Mar 4, 2004
I can't find in this article how can i check if linked server already exist? Thanks
Rick Bray (not verified)
on Oct 3, 2001
I was wondering if it's possible to edit the values in a query of a LinkedServer?
Anonymous User (not verified)
on Nov 4, 2004
I am using IBMDADB2 as well and the four part query was returning the same responses for me. It was only when I used openquery() that I was able to get results.
Nalina (not verified)
on Mar 8, 2004
I tried to create linked server to access in SQL sever using the steps outlined in this article. However, I keep getting the error 7339 message . I tried to look up explanation for this error on the net and tried to resolve it based on the suggestions listed in those articles but with no success. Also I tried to set up a linked server to dataware house its giving me err 7303, could not initialize the provider IBMDADB2, this comes if I use the provider IBM OLE DB Provider for DB2 servers, the DSN for datawarehouse has been set up using IBM DB2 ODBC DRIVER. If I use MS OLE DB FOR ODBC DRIVER for datawarehouse than I get err 7399. Can you please let me where I am going wrong. I have wasted a lot of time on this. Your help is much appreciated Nalina
Chris Singleton (not verified)
on Oct 10, 2002
I have configured a linkedserver in SQL Server 2000 to a DB2 (AS/400) database using Microsoft's Oledb provider for DB2. I'm also using Host Integration Server with SP1 as my gateway. I can issue "select" statements through the server but "Inserts", "updates" and "deletes" do not work. Can you help me with this?
Anonymous User (not verified)
on Nov 23, 2004
My shop recently installed a packed application which uses SQL Server 2000 as the database and UDB on AIX as the enterprise database to replicate data to and from. We use the Linked server with IBM OLE DB provider to access the enterprise data. The vendor for the package application recommends us to enable "ALLOW INPROCESS" option on the linked server. On the daily basis we run two batch jobs to upload and download (replicate) data between the two heterogenous databases. However, we are experiencing memory problem after a few runs of the batch jobs. The memory usage of the SQL server grows every time we run the batch and did not release it (the memory). As a temporary solution, we have to stop and start the SQL server. To us, it looks like a memory leaks, however Microsoft technical does not agree with it. Do you have any hints or tips how to resolve it. Perhaps some option parameters that we have to check on or off ? Thank you. Regards, T Tan tantekh@manulife.com
Anonymous User (not verified)
on Nov 17, 2004
I have stored procedure that I am running in SQL Server 2000 that uses the OpenQuery(). This works great when I run it from SQL Server, but I try to execute it in a Visual Basic app using ADO and I get the following message: [OLE/DB provider returned message: [Microsoft][ODBC driver for Oracle]Driver not capable]. I was wondering if anyone knew of a solution as to why this happens. Many thanks in advance. Eddie
sagemcenery
on Dec 28, 2006
for the person looking to see if a linked server exists, you can check the output of sp_LinkedServers, or you can do what the sp_linkedServers procedure does and run the following select * from master.dbo.sysservers Where srvname = @YourLInkedServerName
Jose (not verified)
on Jul 24, 2000
I have an Oracle 8i running on NT and the Select statement using the OPENQUERY method mentioned in your article (SELECT * FROM OPENQUERY(LINKEDSERVER, "SELECT * FROM northwind..Categories where CategoryName Like 'Sea%'") does not work with quotation marks. It works with a single quote but then I have trouble with the WHERE statement ( 'Sea%' ) Can you help me with this problem? Jose Lucero Real Property Technologies

Please or Register to post comments.

IT/Dev Connections

Las Vegas
September 30th - October 4th

Paul ThurottOur Experts will show you:
• Common SQL Server
Problems
• Best Practices for T-SQL
• SQL Server Integration
Services
• Database Development

Come See Michael Otey & Tim Ford in Person!

Early Registration Now Open

From the Blogs
May 21, 2013
blog

A Common Misconception about MAXDOP

Out of the box, SQL Server is (and has been) able to take advantage of multiple processors/cores without any effort on behalf of administrators....More
May 9, 2013
blog

My ISO 8601-Compliant Signature 2

My family recently just "officially" announced that we're in the process of adopting a child from South Africa. We're quite excited, of course, but there's a ton of paperwork to do—along with the need for gobs of signatures....More
May 8, 2013
blog

Use SSIS for ETL from Hadoop

In this blog post, Mark Kromer walks you through using SSIS as a way to use ETL techniques using Microsoft's Hadoop on Windows (HDInsight) as a source using Hive connectors...More
SQL Server Pro Forums

Get answers to questions, share tips, and engage with the SQL Server community in our Forums.