DB2 Integration with SQL Server 2005, Part I: Linked Server Enhancements PDF Print E-mail
Written by Michael Sansoterra   
Tuesday, 07 March 2006

Check out SQL Server 2005's new features that simplify integration with other databases.

As the old saying goes, "good things come to those who wait." At last, the long-anticipated release of SQL Server 2005 has finally arrived, and there are plenty of good things in it. This article focuses on how SQL Server 2005 makes integration with the DB2 database easier thanks to linked server enhancements.

What Is a Linked Server?

Introduced way back in SQL Server 7.0, linked servers allow SQL Server to query OLE DB and ODBC data sources. This means a data source can be another SQL Server, a DB2 database, a spreadsheet, a text file, or almost any other data store. Once the linked server has been defined, remote data sources can participate in joins with local tables or other linked servers. Depending on the capability of the OLE DB provider, the linked server data source may even be updateable. For instance, SQL Server can be used to update or delete rows in the table of a DB2 database based on records in a local table.

As a brief review of using linked servers in Transact-SQL (T-SQL is SQL Server's dialect of SQL), say we have a linked server called DB2400 that points to a DB2 database on the iSeries. Data can be queried from the linked server by using a four-part naming convention or by using the OpenQuery function:

-- Query DB2 table using four part table name
Select * 
  From DB2400.S104X824.QIWS.QCUSTCDT A
  Join CustInfo.dbo.customers B On B.CustomerId=A.CustID

-- Query DB2 table using OpenQuery function
Select * 
  From OpenQuery(DB2400,
       'Select * From QIWS.QCUSTCDT') As Remote
  Join CustInfo.dbo.customers B On B.CustomerId=Remote.CustID

Of course, more complicated queries can be constructed. For a thorough review of linked servers and their capabilities, see "Running Distributed Queries with SQL/400 and SQL Server 7.0" (AS/400 Network Expert, September/October 2000) and "Patch Those Leaky Interfaces" (MC Mag Online, June 2003).

Setting Up a Linked Server

A linked server must be configured before it can be used. Setup requires two steps:

  1. Install the desired ODBC driver and set up a data source name (or install the desired OLE DB provider). This article uses the ODBC driver that comes with iSeries Access V5R3.
  2. Create the linked server by using T-SQL statements (or by using the new SQL Server Management Studio object explorer graphical interface. Expand the Server Objects node to find the Linked Server definitions. Note: This location for maintaining linked servers is a change from the SQL Server 2005 beta and prior editions of SQL Server, where linked servers were located under the Security node.)

The code below demonstrates how to create a linked server called DB2400 that is based on an ODBC connection with a DSN name called AS400:

--
-- Create Linked Server using ODBC DSN "AS400"
--
sp_addlinkedserver 
    @server=N'DB2400', 
    @srvproduct=N'DB2 UDB for iSeries',
    @provider=N'MSDASQL',
    @datasrc=N'AS400',
    @provstr='CMT=0;SYSTEM=as400.mycompany.com',
    @catalog='S104X824'
go
--
-- Define the credentials that will be used to
-- access objects hosted by the Linked Server
--
sp_addlinkedsrvlogin @rmtsrvname=N'DB2400',
                     @useself='false',
                     @rmtuser=N'MyUser',
                     @rmtpassword='MyPassword'
go
--
-- RPC option is required for doing EXEC AT
--
EXEC sp_serveroption 'DB2400', 'rpc out', true
go

The built-in stored procedure sp_addlinkedserver is used to register a linked server. The provider name in this case is MSDASQL, which is the OLE DB wrapper around the ODBC APIs. The data source (datasrc) parm contains the name of the ODBC DSN, which is configured under administrative tools (on Windows 2000 and above). The provider string (provstr) parameter overrides any of the ODBC DSN's default settings. Finally, the catalog parameter should be the name of the relational database entry for your iSeries (by default, it is the same as the system name.)

Stored procedure sp_addlinkedsrvlogin defines the login credentials for the server. In the example, the rmtUser and rmtPassword entries dictate the credentials to be used when SQL Server attempts to access a resource on the linked server.

Finally, in order for a linked server to use some of the new linked server features, the rpc out setting must be set to true. This can be accomplished programmatically by using sp_serveroption, as shown in the example.

To remove the linked server entry, issue the following commands:

sp_droplinkedsrvlogin @rmtsrvname=N'DB2400',@locallogin=Null
go
sp_dropserver @server=N'DB2400'
go

Latest Enhancements

SQL Server's ability to access remote data sources via linked servers often makes the programmer's life easier by easily allowing remote data to be joined and updated using T-SQL. However, linked servers have suffered from a few deficiencies, including the inabilities to use parameter markers, execute stored procedures, and execute Data Definition Language (DDL) statements such as CREATE TABLE. Under these circumstances, Data Transformation Services (DTS) or another tool was used.

These other programming options may no longer be needed because linked servers have increased capability. The EXEC command has been enhanced with an AT clause to specify that an SQL statement should execute on a linked server:

EXEC statement AT linked server.

Keep in mind that the SQL statement submitted with EXEC AT will be in the SQL dialect of the remote server (in this case DB2).

Using the DB2400 linked server (defined above), here is a sample of how to use EXEC AT to retrieve data from the iSeries:

--
-- As with OpenQuery, enhanced EXEC support allows pass 
-- through queries to be executed on a linked server.
--
EXEC ('SELECT * FROM DATALIB.OrderHdr WHERE OrderID>1') 
AT DB2400

Here is an example of issuing a DDL statement followed by an insert to a remote DB2 table using the four-part table convention:

--
-- EXEC AT can issue DDL statements
--
EXEC ('Create Table DATALIB.OrderTemp 
(OrderId Int Not Null, PartId Char(15) Not Null)'
AT DB2400
GO

Insert Into DB2400.S104X824.DATALIB.ORDERTEMP
Values(1,'BICYCLE')
GO

This kind of power allows a developer to write a program capable of complex cross-platform database access entirely in T-SQL.

Further, parameter markers can now be used to create optimized, re-useable statements. Here is an example of how the previous insert statement can be done using the new EXEC AT syntax:

-- Insert Example
Declare @OrderId Int
Declare @PartId  Char(15)
Set @OrderId=2
Set @PartId='MOTORCYCLE'
EXEC ('Insert Into DATALIB.OrderTemp Values (?,?) 
       With NC',@OrderId,@PartId) AT DB2400

Update statements are allowable as well:

-- Update example
Declare @OrderId Int
Declare @PartId  Char(15)
Set @OrderId=2
Set @PartId='MOTORCYCLE1'
EXEC ('Update DATALIB.OrderTemp 
          Set PartId=? 
        Where OrderId=?',@PartId,@OrderId) AT DB2400

Keep in mind that, while most Data Manipulation Language (DML) statements can also be accomplished with the traditional four-part syntax, EXEC AT allows the additional flexibility of using things like built-in functions and user-defined functions that are defined only on the host. For example, if you need to use a datalink-related DB2 function, you would only be able to invoke this function using EXEC AT because T-SQL knows nothing about the DB2 datalink data type and related functions.

Here's an example of a stored procedure call that accepts a parameter.

Set NoCount On
Declare @OrderID Int
Set @OrderID=10249
--
-- Call Parameterized Stored Procedure
--
Exec ('Call DATALIB.GetOrders (?)', @OrderID) AT DB2400

To retrieve the result of an output variable from a stored procedure, specify the OUTPUT keyword after the variable name, as follows:

-- Test Stored Proc with output variable
Set NoCount On
Declare @OrderID Int
Exec ('Call DATALIB.GETNEXTORDER (?)', @OrderID OUTPUT) AT DB2400

Select @OrderID

If the stored procedure produces a result set, it will be returned as well. This can be beneficial in a client/server environment for applications using both DB2 and SQL Server calls because both systems can be accessed from a single SQL Server connection. This setup relieves the need to have DB2 connectivity installed and configured on each desktop.

One drawback of EXEC AT is the limited programmatic support for SELECT and stored procedure result sets. While EXEC AT provides the ability to specify complex and parameterized SELECTs that will execute more efficiently on the remote server, EXEC AT does not allow joins or programmatic access to the result set. However, this limitation can be overcome by returning the results from EXEC AT to a temporary table using the INSERT/EXEC statement.

--
-- The following Insert Exec example requires
-- a Distributed Transaction so the MS-DTC
-- service must be running.
--
Set NoCount On
Declare @OrderID Int
Set @OrderID = 10248

If Object_ID('tempdb..#tmpOrderHdr') Is Not Null
    Drop Table #tmpOrderHdr

Create Table #tmpOrderHdr
(OrderID    Int Not Null Primary Key,
 CustomerID VarChar(5) Not Null)

--
-- Insert data into local SQL Server table
-- from parameterized SELECT in DB2
--
Insert Into #tmpOrderHdr
Exec ('SELECT OrderID,CustomerID 
         FROM DATALIB.OrderHdr 
        WHERE OrderID=? With NC', @OrderID) AT DB2400
--
-- Do programmatic access to result set 
-- such as cursor processing or JOINs here.
--
Select *
  From #tmpOrderHdr

Alternatively, INSERT/EXEC can be used against a stored procedure instead of a SELECT:

--
-- A DB2 stored procedure can be executed
--
Set @OrderID = 10249
Insert Into #tmpOrderHdr
Exec ('Call DATALIB.GetOrders (?)', @OrderID) AT DB2400

Running INSERT/EXEC against a linked server requires a distributed transaction. In a nutshell, a distributed transaction (DT) creates an environment where database consistency and atomicity concepts are broadened across multiple database (even heterogeneous) servers. In a DT, data modifications must be successful on multiple systems in order for the changes to be committed. Whereas transactions in the DB2 world normally require journaling, it is not required in this scenario to run an INSERT/EXEC statement.

To use a distributed transaction, the following setup is required:

  • The MS-DTC (distributed transaction coordinator) service must be running.
  • You must have iSeries Access V5R1 or higher (make sure to use the latest service pack as there have been various bugs).
  • The MS-DTC service should have support for XA transactions enabled. On a Windows XP machine, this can be accomplished by selecting Control Panel -> Administrative Tools -> Component Services. Expand the component services and computers node. Right-click on My Computer and choose Properties. Select the MSDTC tab and choose the Security Configuration button. Next, click on Enable XA Transactions. Figure 1 shows a sample configuration screen shot.


http://www.mcpressonline.com/articles/images/2002/Linked%20Server%20EnhancementsV4--03220600.jpg

Figure 1: Here's an example of what your configuration screen would look like. (Click image to enlarge.)

For more information on distributed transactions, click here.

OLE DB Provider IBMDASQL

Linked servers use Microsoft's OLE DB technology. OLE DB providers are often preferred over ODBC drivers because using ODBC requires an extra programmatic interface layer between the OLE DB and ODBC standards. However, in the case of the iSeries, the ODBC driver offers the better of the two options because it supports more features. Because IBM continues to enhance the OLE DB providers for the iSeries, I thought it worthwhile to test one of them.

iSeries Access V5R3 comes with a new SQL-only OLE DB provider called IBMDASQL. Below is a T-SQL script that defines a linked server called DB2400OLEDB that uses the IBMDASQL provider.

sp_addlinkedserver @server=N'DB2400OLEDB', 
                   @srvproduct=N'DB2400 UDB for iSeries',
                   -- IBMDA400/IBMDASQL are OLE DB providers 
                   -- for DB2 UDB for iSeries. IBMDASQL is
                   -- available with iSeries Access V5R3
                   @provider=N'IBMDASQL',
                   -- System Name
                   @datasrc=N'AS400.MYCOMPANY.COM',
                   @catalog='S104X824'

go

sp_addlinkedsrvlogin @rmtsrvname=N'DB2400OLEDB',
                     @useself='false',
                     @rmtuser=N'MyUser',
                     @rmtpassword='MyPassword'
go
--
-- RPC option is required for doing EXEC AT
--
EXEC sp_serveroption 'DB2400OLEDB', 'rpc out', true

By substituting the DB2400OLEDB linked server name in the prior T-SQL examples, I found a mixture of things that did and didn't work (including differences in what worked in the SQL Server 2005 June CTP beta vs. the released product). Because of these issues, I wouldn't recommend using IBMDASQL at this time.

The Integration Factor

When integrating data from heterogeneous data sources, what used to take loads of time to program now can be done quickly thanks to these linked server enhancements. And if SQL Server 2005's linked servers don't offer enough data access versatility, custom stored procedures and table-valued functions can be written in a .NET programming language such as C# or VB.NET. I'll discuss this concept in Part 2 of this series.

If you're thinking of upgrading to SQL Server 2005, know that there are plenty of new tools to help with data integration challenges, whether with the iSeries edition of DB2, Oracle, or MySQL. Microsoft has done a good job of creating versatile and easy-to-use programming tools to make disparate systems talk seamlessly.

Michael Sansoterra is a developer at i3 Business Solutions, an IT services firm based in Grand Rapids, Michigan. You can reach him at This e-mail address is being protected from spam bots, you need JavaScript enabled to view it .


Last Updated ( Tuesday, 07 March 2006 )
 
Discuss (18 posts)
rtimbers
DB2 Integration with SQL Server 2005, Part I: Linked Server Enhancements
May 16 2007 00:59:00
Hi, <p>I had the same error and it was because I was running SQL 2005 under a service account I'd created rather than a Local system account. <p>To fix: <p>Expand Component Services - Computers - My Computer - DCOM Config <BR>
Select MSDAINITIALIZE Right Click properties then security <p>Under Security - Launch Permission: enable Local Launch and Local Activation for your SQL Service account <p>Under Security - Access permissions: Allow System: Local Access and Remote Access. <p>After that everything worked ok
#119868
B_LEE
DB2 Integration with SQL Server 2005, Part I: Linked Server Enhancements
Nov 29 2006 16:59:00
Hi, <p>I tried to add a link server in SQL 2005 to access iSeries (V5R3) based on the section "OLE DB Provider IBMDASQL" of the article. The following is my T-SQL: <p>EXEC master.dbo.sp_addlinkedserver @server = N'LinkServerName', <BR>
&nbsp;@srvproduct=N'IBMDASQL', @provider=N'IBMDASQL', <BR>
&nbsp;@datasrc=N'iSeriesName', @catalog=N'LibraryName' <BR>
and then I add the security info to the link server. When I run my following select statement <p>Select * From OPENQUERY(LinkServerName, 'select * from LibraryName.FileName') <p>I have following error message: <BR>
Msg 7302, Level 16, State 1, Line 1 <BR>
Cannot create an instance of OLE DB provider "IBMDASQL" for linked server "LinkServerName". <p>Did I missed anything? Can any one help? Thanks
#119867
Guest.Visitor
DB2 Integration with SQL Server 2005, Part I: Linked Server Enhancements
Nov 20 2006 13:11:00
To see if a port is blocked go to GRC.com's Shields up at <BR>
<a href="https://www.grc.com/x/ne.dll?bh0bkyd2">https://www.grc.com/x/ne.dll?bh0bkyd2</a>.<BR>
<P>
<P>
"tinoq" <tinoq@mcpressonline.com> wrote in message <BR>
news:6b349fe0.13@WebX.WawyahGHajS...<BR>
> How do you check if a port is blocked or not? And how do you unblock<BR>
> it? Thanks. <BR>
<P>
<P>
#119866
tinoq@yahoo.com
DB2 Integration with SQL Server 2005, Part I: Linked Server Enhancements
Nov 20 2006 00:09:00
How do you check if a port is blocked or not? And how do you unblock <BR>
it? Thanks.
#119865
Guest.Visitor
DB2 Integration with SQL Server 2005, Part I: Linked Server Enhancements
Nov 18 2006 09:54:00
Could it be that the iseries port for odbc is closed or blocked for security reasons? A number that comes to mind for the odbc port for iseries is 50000. <p>Tom.
#119864
tinoq@yahoo.com
DB2 Integration with SQL Server 2005, Part I: Linked Server Enhancements
Nov 17 2006 18:48:00
I tried CWBPING and I got this: <p>C:>CWBPING 192.168.118.5 <p>IBM iSeries Access for Windows <BR>
Version 5 Release 3 Level 0 <BR>
Connection Verification Program <BR>
(C) Copyright IBM Corporation and Others 1984, 2003. All rights reserved. <BR>
U.S. Government Users Restricted Rights - Use, duplication or disclosure <BR>
&nbsp;&nbsp;restricted by GSA ADP Schedule Contract with IBM Corp. <BR>
Licensed Materials - Property of IBM <p>To cancel the CWBPING request, press CTRL-C or CTRL-BREAK <BR>
I - Verifying connection to system 192.168.118.5... <BR>
I - Successfully connected to server application: Central Client <BR>
I - Successfully connected to server application: Network File <BR>
I - Successfully connected to server application: Network Print <BR>
I - Successfully connected to server application: Data Access <BR>
I - Successfully connected to server application: Data Queues <BR>
I - Successfully connected to server application: Remote Command <BR>
I - Successfully connected to server application: Security <BR>
I - Successfully connected to server application: DDM <BR>
I - Successfully connected to server application: Telnet <BR>
I - Connection verified to system 192.168.118.5
#119863
Guest.Visitor
DB2 Integration with SQL Server 2005, Part I: Linked Server Enhancements
Nov 17 2006 13:05:00
Just a thought, but it sounds like there's a problem connecting to your iSeries. Try using "CWBPING servername" from a command-line, using the same servername you put in your ODBC DSN. <p>Cliffe
#119862
tinoq@yahoo.com
DB2 Integration with SQL Server 2005, Part I: Linked Server Enhancements
Nov 17 2006 13:02:00
Thank you for the article, but I could get it to work using ODBC DSN <BR>
when executing this SQL: <BR>
&nbsp;&nbsp;SELECT * From OpenQuery(DB2400, 'SELECT * FROM QIWS.QCUSTCDT') <p>I'm getting this error: <BR>
&nbsp;&nbsp;"[IBM][iSeries Access ODBC Driver]Communication link failure. comm rc=11004 - CWBCO1011 - Remote port could not be resolved". <p>Msg 7303, Level 16, State 1, Line 1 <BR>
Cannot initialize the data source object of OLE DB provider "MSDASQL" for linked server "DB2400". <p>PLEASE HELP.
#119861
Guest.Visitor
DB2 Integration with SQL Server 2005, Part I: Linked Server Enhancements
May 18 2006 18:11:00
Thank you for your article! but I found when I tried to create my linked server using the odbc that the 4 part name was case sensitive. <BR>
I ONLY COULD GET MY LINKED SERVERS TO WORK IF I USED UPPERCASE.
#119860
Guest.Visitor
DB2 Integration with SQL Server 2005, Part I: Linked Server Enhancements
Apr 28 2006 14:59:00
Hi, <p>I read your article regarding linked server in SQL 2005. It worked perfect when I am running myself, but under the job it failed with the following error <p>Access to the remote server is denied because the current security context is not trusted. [SQLSTATE 42000] (Error 15274). The step failed. <p>My linked server is using this secruity settings <p>"Be made using this security context" AS400UserID, AS400Password on the security tab on the linked server. <p>I have even tried to run this job (Run AS ) my user but still the same error coming. <p>Please help.
#119859
Guest.Visitor
DB2 Integration with SQL Server 2005, Part I: Linked Server Enhancements
Mar 09 2006 10:30:00
Thanks again for your help. I still got the same error, even using "FORCE TRANSLATE=37". Strange. I'm on CA/400 V5R2. <p>However, I used an ODBC DSN, and was able to make it work, so that's the main thing. <p>Thanks again, and I look forward to Part II of this series and beyond. <p>Cliffe
#119858
M.Sansoterra
DB2 Integration with SQL Server 2005, Part I: Linked Server Enhancements
Mar 08 2006 19:19:00
Sorry - I gave you a bum steer (I just presumed you were using the ODBC driver). When using the OLE DB provider IBMDA400, you should specify: <p>FORCE TRANSLATE=37 <p>However, you need to be at V5R1 or higher. I tried it on a V5R4 system (using iSeries Access V5R4) and it worked fine.
#119857
Guest.Visitor
DB2 Integration with SQL Server 2005, Part I: Linked Server Enhancements
Mar 08 2006 18:31:00
Thanks for the tip, but I'm still getting an error: <p>Cannot initialize the data source object of OLE DB provider "IBMDA400" for linked server "MYISERIES" <p>The statement to create the linked server (using Client Access' IBMDA400 OLEDB driver) was this: <p>EXEC master.dbo.sp_addlinkedserver @server = N'MYISERIES', @srvproduct=N'IBMDA400', @provider=N'IBMDA400', @datasrc=N'MYISERIES', @catalog=N'S7809323', @provstr='FORCETRANSLATE=1' <p>If I don't put the @provstr argument in, it works, but I get gibberish from queries. <p>Thanks again, <BR>
Cliffe
#119856
M.Sansoterra
DB2 Integration with SQL Server 2005, Part I: Linked Server Enhancements
Mar 08 2006 11:56:00
Hi Cliffe <p>You're on the right track. In your provider string, simply specify: <p>TRANSLATE=1 <p>or <p>FORCETRANSLATATION=1 <p>This switch is either turns translation on or off, you can't specify a from CCSID.
#119855
M.Sansoterra
DB2 Integration with SQL Server 2005, Part I: Linked Server Enhancements
Mar 08 2006 11:53:00
Hi David <p>You are correct -- there are some problems between DB2 and SQL Server that you have to watch for. If you exceed the max rows allows in SQL Server then there's nothing you can do about that. However, DB2 on the iSeries allows you to work around some special character problems (such as an embedded dot) by using double quotes. So the following query will work from SQL Server: <p>Select * <BR>
&nbsp;&nbsp;From OpenQuery(DB2400,'Select * From DATALIB."DOT.TEST"') A <p>Also, if you're using four part table names, this will work as well: <p>Select * From DB2400.S107X248.DATALIB."DOT.TEST" <p>Another issue I've come across is the date data type -- DB2 can hold a much broader range of dates in its ISO data type (starting from year 1, whereas SQL Server starts in the 1700s if I remember right.) For these types of issues you just have to program around them in your query.
#119854
Guest.Visitor
DB2 Integration with SQL Server 2005, Part I: Linked Server Enhancements
Mar 08 2006 11:32:00
Thanks a lot for a good article! I've seen the Linked Servers option before, but hadn't been able to make it work. <p>One question for you - do you know how to return data that's CCSID 65537? Normally, in my Connection String, I'll add "Force Translate=37", but I'm not sure how to do that here. I tried adding in @provStr='Force Translate=37;', but no good. Any suggestions? <p>Cliffe
#119853
David Abramowitz
DB2 Integration with SQL Server 2005, Part I: Linked Server Enhancements
Mar 08 2006 09:20:00
This is a most interesting development. <p>It should be interesting to see what happens when a DB2 feature is being used that is not supported by MS. <p>For instance would this still work if the file contained an embedded dot in the file name, or if the file contained more than a billion records? <p>Dave
#119852
MC Press Web Site Staff
DB2 Integration with SQL Server 2005, Part I: Linked Server Enhancements
May 16 2007 00:59:00
This is a discussion about <B>DB2 Integration with SQL Server 2005, Part I: Linked Server Enhancements</b>.<p align='center'><a href=http://www.mcpressonline.com/mc?1@232.1KNKfHX1eQT.17@.6b344718>Click here for the article</a>.</p>
#119851


Discuss...
User Rating: / 9
PoorBest 
Related Articles
< Prev   Next >

   MC-STORE.COM