Click here to Skip to main content
Click here to Skip to main content

How to link different data sources together

, 11 Jun 2005
Rate this:
Please Sign up or sign in to vote.
Describes how you can link SQL Server with many different data sources like a directory as Active Directory Application Mode, a Microsoft Indexing Server catalog, a Microsoft Access database and a Microsoft Excel spreadsheet. Also explains how to query linked servers using the OPENQUERY command.

Introduction

In today's enterprises, different types of data are sitting in various data stores. Relational data is most likely to be in a SQL Server database or Oracle database. Many enterprise applications have their own database with its own data and data model. User and account information reside in a directory like Active Directory or Active Directory Application Mode. For more information about the directory services, please refer to the following article. Smaller, more fluent and mobile data sits in Excel spreadsheets or Microsoft Access databases. Each enterprise has large amounts of files like Word documents, Excel Spreadsheets, HTML documents, etc. which are sitting on a file system. It's a common practice to use Microsoft Indexing Server to index all the files sitting on the file system or a web server. Microsoft Indexing Server creates an indexing catalog and also provides a SQL query interface which enables you to simply search the index. For more information about Microsoft Indexing Server please refer to the following article.

The challenge enterprises are facing now is how to provide a complete and easy view into all this data sitting in various stores. More over how can you search all this data in various data sources without having to create many different interfaces or create complex search mechanisms? The good news is that most of these data stores provide a SQL query language. The SQL language varies slightly from one data source to another. For example directories like Active Directory provide a query capability but do not allow you to update, insert or delete data through SQL language. The same holds true for the SQL language of Microsoft Indexing Server. But most of the data sources provide the basic SQL query capability. Moreover Microsoft SQL Server allows you to link to other data stores which provide a SQL query language. This allows you to create a single SQL query spawning multiple data sources. This article explains how you can achieve this.

Linking other data stores to Microsoft SQL Server

Microsoft SQL Server provides the capability to link to other data sources which provide SQL query language. The Enterprise Manager of SQL Server shows in the left side navigation pane the "SQL Server groups" and under each all the database servers. It shows by default the local database server as "(local)". You can link other data stores to individual database servers. Expand a database server with the plus sign and you will find an entry called "Security". Expand the "Security" entry with the plus sign and you will see an entry called "Linked Servers". Expand the "Linked Servers" entry to see all the data stores which have been linked to this database server.

To link a new data store, right click on the entry "Linked Servers" and select "New Linked Server" from the popup menu. In the "Linked Server Properties" dialog you can enter a name for this linked server and then select whether you want to link another SQL Server database or any other data source. If you choose "SQL Server" then the linked server name must be the name of the SQL Server database you want to link to. For example if you have another SQL Server database running on the machine Enterprise-Minds then you would enter "Enterprise-Minds" as the linked server name. If you choose "Other data source" then you need to select from a list of existing data source providers, for example "Microsoft Jet 4.0 OLE Provider". Based on which provider you choose you need to enter the product name, data source, provider string, location and catalog. When you are done, click OK to create a link to this new data store. This new data source will now show up under "Linked Servers" with whatever name you had entered.

Link Microsoft SQL Server to a directory

You can link SQL Server to a directory like Active Directory or Active Directory Application Mode. Create a linked server in the Enterprise Manager and give it a descriptive name like "Active Directory Link". Choose the option "Other data source" and select the data provider "OLE DB Provider for Microsoft Directory Services". As product name enter "Active Directory Services" and as data source enter "adsdatasource". When you expand the new linked server you will find two available items - Tables and Views. So SQL Server allows you to view any tables or views in this data source. But the data provider "OLE DB Provider for Microsoft Directory Services" does not provide either the tables or views. Therefore you will get the error "Error 7301: Could not obtain a required interface from OLEDB provider ADsDSOObject". You can safely ignore the error message. You will be able to query the data store through the SQL query language.

It is important that you run the services "MSSQLSERVER" under an account which has access to the directory. If you run the services under the local system account you will get the following error when you try to query the data store:

Server: Msg 7321, Level 16, State 2, Line 1
An error occurred while preparing a query for 
         execution against OLE DB provider 'ADsDSOObject'.
OLE DB error trace [OLE/DB Provider 'ADsDSOObject' 
                    CommandPrepare::Prepare returned 0x80040e14].

So if the directory runs on your local machine and the local user "DirectoryUser" has access to it then you need to run the "MSSQLSERVER" service under this account. If the directory is running somewhere in your domain and the domain user "DomainUser" has access to it then you need to run the "MSSQLSERVER" service under this domain account.

Link Microsoft SQL Server to a Microsoft Indexing Server catalog

You can also link SQL Server to an Indexing Server catalog. Create a new linked server and give it a descriptive name, for example WEBCATALOG if you are linking to the Web Indexing Server catalog. Next select "Other data source" and choose as data provider "Microsoft OLE DB Provider for Indexing Service". Enter as product name "Index Server" and as data source the name of the Indexing Server catalog, for example Web. When you expand the new linked server you will find two available items - Tables and Views. So SQL Server allows you to view any tables or views in this data source. But the data provider "Microsoft OLE DB Provider for Indexing Service" neither provides the tables nor views. Therefore you will get an error "Error 7301: Could not obtain a required interface from OLEDB provider MSIDXS". You can safely ignore the error message. You will be able to query the data store through the SQL query language.

Link Microsoft SQL Server to a Microsoft Access database

SQL Server can also be linked to a Microsoft Access database. Create a new linked server and give it a descriptive name, for example "Booklist". Next select "Other data source" and choose as data provider "Microsoft Jet 4.0 OLE DB Provider". Enter as product name "Access" and as data source the path to Microsoft Access file, for example "c:\My files\Books.mdb". This data provider is able to show the list of tables and views. So when you expand the Table's or View's item under this linked server you will see the list of tables or views in the Microsoft Access database.

Link Microsoft SQL Server to a Microsoft Excel spreadsheet

SQL Server can also be linked to a Microsoft Excel spreadsheet. Create a new linked server and give it a descriptive name, for example "Booklist". Next select "Other data source" and choose as data provider "Microsoft Jet 4.0 OLE DB Provider". Enter as product name "Jet 4.0", as data source the path to the Microsoft Excel spreadsheet - for example "c:\My files\Books.xls" - and finally as provider string enter "Excel 5.0". This data provider shows under Tables the list of excel worksheets. It does not show any Views.

There are many other providers available, which allow you to link up SQL Server with a variety of different data sources. The following link lists some of the available data providers which can be used by SQL Server.

How to query linked servers?

Now we have learnt how to link SQL Server with a variety of different data stores. To query data from a linked server you can use the command OPENQUERY in your FROM clause, which means you can query data from a linked server instead of a standard SQL Server table or view. The command OPENQUERY requires two parameters. First is the name of the linked server followed by the query you want to execute against this linked server. The following example assumes that you have a linked server with the name Books which has a table called Books:

SELECT * FROM OPENQUERY(Books, 'SELECT * FROM Books') AS Books

The query you pass along in the OPENQUERY command needs to be supported by the linked data provider. So depending on the data provider it might vary slightly. You can join the data from any linked data source or SQL Server table together. The next example assumes that you query a linked data source and join it together with a SQL Server table called BookValue.

SELECT * FROM OPENQUERY(Books, 'SELECT * FROM Books') AS Books INNER JOIN 
BookValue ON Books.ID = BookValue.ID

How to query a directory?

The "OLE DB Provider for Microsoft Directory Services" accepts two different syntaxes. One is called the LDAP dialect and the other the SQL dialect . As its name suggests the SQL dialect follows the SQL language syntax. You specify for the SELECT keyword the directory attributes you want to query for. For the ORDER BY and WHERE keywords you specify the attributes to sort on and to filter by. And for the FROM keyword you specify which directory and directory container to query for. The following example queries the container "OU=Enterprise-Minds,CN=Vancouver" in the Enterprise-Minds directory. It returns the common name and returns only the directory objects of the type group.

SELECT * FROM OPENQUERY(ADAM,
  'SELECT cn FROM ''LDAP://Enterprise-Minds/OU=Enterprise-Minds,
   CN=Vancouver'' WHERE objectClass=''group'' ')

Please note that the FROM clause needs to be put under two single quotes (escape sequencing of single quotes within a string which is already under single quotes). The following example queries the common name and the ADS path for any directory object residing in the container "OU=Enterprise-Minds,CN=Vancouver" in the Enterprise-Minds directory.

SELECT * FROM OPENQUERY(ADAM,
 'SELECT cn, ADsPath FROM ''LDAP://Enterprise-Minds/OU=Enterprise-Minds,
  CN=Vancouver'' ')

The LDAP dialect consists of four parts, each separated by a semicolon. The first part specifies the directory and the directory container, the second part the filter, the third part the list of attributes to return and the last part the scope of the search. The scope part can have three values - Base, OneLevel and SubTree. Base searches only the directory path that you specify. OneLevel searches the immediate children of the directory path that you specify. And SubTree searches all the descendants of the directory path that you specify. The following example returns the same information as the first SQL dialect example - the list of all group objects:

SELECT * FROM OPENQUERY(ADAM,
  '<LDAP://Enterprise-Minds/OU=Enterprise-Minds,CN=Vancouver>;
  (objectClass=group);cn;subtree')

The next example returns the same information as the second SQL dialect example - the common name and the ADS path of all directory objects:

SELECT * FROM OPENQUERY(ADAM,
  '<LDAP://Enterprise-Minds/OU=Enterprise-Minds,CN=Vancouver>;;
  cn,ADsPath;subtree')

You can find more information about the possible filter syntaxes at the following article. The filter syntax applies for both dialects with the difference that the values need to be put under single quotes for the SQL dialect. For example you can see that the value group in the SQL dialect example is under single quotes (double single quotes for escape sequencing) while it is not for the LDAP dialect example.

How to query Indexing Server catalogs?

Please refer to the following article for a detailed explanation on how to query Indexing Server catalogs. The following example queries the file name, path and the virtual path for all files in the linked Web Indexing Server catalog.

SELECT * FROM OPENQUERY(WEBCATALOG, 'SELECT FileName, 
                            Path, VPath FROM SCOPE()')

The next example queries for all the files which contain the value "default" and are residing under the "/Info" virtual directory and all its sub directories. It returns for all matches the file name, path and virtual path.

SELECT * FROM OPENQUERY(WEBCATALOG, 'SELECT FileName, Path, VPath FROM 
  SCOPE(''DEEP TRAVERSAL OF("/Info")'') WHERE CONTAINS(FileName,''default'') ')

Please note that the value in the SCOPE function is under two single quotes for escape sequencing, while the value of the DEEP TRAVERSAL OF function is under double quotes, according to the Indexing Server SQL syntax. As shown you can create very complex queries.

How to query Excel spreadsheets?

All worksheets present in a linked Excel spreadsheet are shown as a tables. Note that all the table names show at the end a $ sign. Also if the worksheet name has spaces in it, you see the table name surrounded by single quotes which you always drop in your query. The table name in your query string needs to be surrounded by square brackets. The following example queries for all entries in the worksheet called Summary.

SELECT * FROM OPENQUERY(Books, 'SELECT * FROM [Summary$]')

It is important that the Excel spreadsheet is not open in Excel, otherwise you will get the following error:

Server: Msg 7399, Level 16, State 1, Line 1
OLE DB provider 'Microsoft.Jet.OLEDB.4.0' reported an error. 
    The provider did not give any information about the error.
OLE DB error trace [OLE/DB Provider 'Microsoft.Jet.OLEDB.4.0' 
    IDBInitialize::Initialize returned 0x80004005: The provider 
    did not give any information about the error.].

Summary

This article describes how you can link SQL Server with many different data sources. It describes step by step how to link SQL Server to a directory like Active Directory Application Mode, a Microsoft Indexing Server catalog, a Microsoft Access database and a Microsoft Excel spreadsheet. It also explains how you can query linked servers using the OPENQUERY command of SQL. Finally it explains the query syntax for directory queries, Indexing Server catalog queries and Excel spreadsheet queries. Queries against a Microsoft Access database use the same SQL syntax as you are used to from SQL Server.

Microsoft SQL Server provides a powerful way to link up many different data stores and provide one common query interface. This makes it very easy for applications to provide a common query capability against most data stores in the enterprise. This capability is not widely known in the developer community. Taking advantage of it can simplify your application tremendously if you need to query many different data sources and provide one common query interface and search result. If you have comments on this article or this topic, please contact me @ klaus_salchner@hotmail.com. I want to hear if you have learned something new. Contact me if you have questions about this topic or article.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

klaus_salchner@hotmail.com
Web Developer
Canada Canada
I have worked for 14 years in the industry, nine years in Europe and another five years in North America. As a Senior Enterprise Architect with solid experience in enterprise software development, Klaus spends considerable time on performance, scalability, availability, maintainability, globalization/localization and security. The projects he has been involved in are used by more than a million users in 50 countries on three continents.
 
Klaus calls Vancouver, British Columbia his home at the moment. His next big goal is doing the New York marathon in 2006. Klaus is interested in guest speaking opportunities or as an author for .NET magazines or Web sites. He can be contacted at klaus_salchner@hotmail.com or http://www.enterprise-minds.com.
 
Enterprise application architecture and design consulting services are available. If you want to hear more about it contact me! Involve me in your projects and I will make a difference for you. Contact me if you have an idea for an article or research project. Also contact me if you want to co-author an article or join future research projects!

Comments and Discussions

 
GeneralLinked Server Active Directory (ADSI) Error PinmemberGunjanShah20-Apr-06 2:59 
QuestionOPENQUERY fails when ... PinmemberD e e p s21-Feb-06 0:06 
Hello Everybody / Anybody ,
Sorry but exiting problem!
 
The Problem: OPENQUERY throwing error [Error 7357]when the source SP uses temporary table.
Description : Need to validate data against master list. My combo on UI has a source Stored Proc(contains a temp table in it).
I'm importing data from Excel. Before import, I want to validate it against my master list values.
 
[say field Priority has master values "High, Medium,Low".] and in excel user has added 'ComplexHigh' under priority field]
In this case, my import validator StoredProc should not accept value 'ComplexHigh' as it is not present in my Priority master list]
 
I'm preparing a temp table tabName containing o/p of SP, it works fine zakkas if my SP usp_SelectData does not contain temp table.
I think you got what the situation is!! Woh!
 
Note : I have searched net for this and found nothing! So its challenge for all of us. TRY OUT!!
------------------------------------- The Code ----------------------------
create proc usp_SelectData
as
create table #xx (FixedCol int)
insert into #xx select 1 union select 2
select * from #xx
drop table #xx
 
create proc usp_SelectData2
as
create table xx (FixedCol int)
insert into xx select 1 union select 2
select * from xx
drop table xx
-- Please replace MyDB with your current Database
SELECT * INTO tabName FROM OPENQUERY('EXEC MyDB.dbo.usp_SelectData')
 
-- Throws Error 7357 : [Could not process object 'EXEC MyDB.dbo.usp_SelectData'. The OLE DB provider 'SQLOLEDB' indicates that the object has no columns.]
SELECT * INTO tabName FROM OPENQUERY('EXEC MyDB.dbo.usp_SelectData2') -- Works fine
-----------------------------------------------------------------------------------------------------------------
Thanks in advance...

Generalheterogeneous non-sqlserver queries PinmemberSanti Serrano7-Feb-06 9:41 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.141223.1 | Last Updated 12 Jun 2005
Article Copyright 2005 by klaus_salchner@hotmail.com
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid