Professional Documents
Culture Documents
Summary
This document shows how to configure Microsoft BizTalk Server 2006 with the BizTalk Adapter for DB2. Specifically, the document addresses using send ports to submit commands to the DB2 database.
Contents
Setting Up the BizTalk Adapter for DB2 Using Send Ports.................................................1 Contents............................................................................................................................. 2 Setting Up the BizTalk Adapter for DB2 Using Send Ports ....................................3 Overview......................................................................................................................... 3 Setting Up the Data Connection.....................................................................................3 What Are Updategrams?............................................................................................... 14 BizTalk Configuration.................................................................................................... 18 Visual Studio 2005 Configuration..................................................................................29 ADDENDUM................................................................................................................. 57 Conclusion.................................................................................................................... 68 Copyright...................................................................................................................... 68
Overview
This document contains the following sections: Setting Up the Data Connection What Are Updategrams? BizTalk Configuration Visual Studio 2005 Configuration Data Flow Charts
The information in this document is a general introduction to the previous topics. It is not meant to be an in-depth resource for creating BizTalk applications. Rather, it is intended to help with basic configuration and setup. In most cases, you should start with a basic project such as the one presented in this document, and then build on that as necessary. One indication that everything is going as designed is if the samples work for you.
2. Create a DB2 OLE DB UDL to point to the host. To do this, on the File menu, click New, and then click Data Source. This begins the wizard.
3. On the Data Source Wizard screen, click Next. 4. Select DB2/AS400 for Data source platform, select TCP/IP for Network type, and then click Next.
5. On the TCP/IP Network Connection screen, enter CONTOSO (or any DB2 host) in the Address or alias box.
6. The default port for AS/400 is 446. If your port is different, change this field, and then click Next. This brings up the DB2Database screen. Settings on this page will depend on your DB2 system. For DB2/400, the initial catalog is the RDBNAME (the database name of the remote computer). (Use the WRKRDBDIRE command from an AS/400 console.) For DB2 (MVS, OS/390), this is referred to as LOCATION. For DB2/UDB, this property is referred to as DATABASE. For more information about these properties, click Help at the bottom of the page.
7. Fill in the appropriate values. In the preceding screen, the RDBNAME is S10D823B, the package collection is the name of the AS/400 library (CNWIND, in this case), and the default schema is also set to CNWIND (target collection). Note If the database file is in a different library than indicated in the default schema, the default qualifier field should point to the library that hosts the file. 8. Click Next. 9. Set the appropriate values for Host CCSID and PC code page, and then click Next.
10. On the Security screen, enter the security method that you wish to use, and fill in the appropriate fields. In this example, the security method is Interactive sign-on, and the password will be saved to the UDL, which will be created later in this wizard. Note These fields are case-sensitive. 11. Once you have filled in the information for your security method, click Next.
12. On the Advanced Options screen, for most purposes when using the adapter, you can leave the options as cleared, and then click Next.
10
The Validation screen appears. If you click Connect, the DB2 provider verifies whether it can do a basic connection (for instance, no password required) to the DB2 system. A successful connection should have output similar to this: Successfully connected to data source 'New Data Source'. Server class: DB2/400 Server version: 05.04.0000 13. Click Sample Query. This should return the tables on the host from the information that you have provided in previous steps.
11
14. Click Packages. This creates DB2 packages that are required for executing SQL statements. Creating packages on DB2 requires authority to CREATE, BIND, and GRANT privileges to PUBLIC. If you do not have sufficient authority (with the user ID/password given earlier in the Security screen), contact the database administrator. When this is run on AS/400, you should end up with output similar to this: Connected to data source 'New Data Source'. AUTOCOMMITTED package has been created. READ COMMITTED package has been created. READ UNCOMMITTED package has been created. SERIALIZABLE package has been created. REPEATABLE READ package has been created. The package creation process has completed successfully. After performing the preceding action in the Validation screen, click Next to continue to the Saving Information screen. 1. In the Data source name text box, type the name, and then select the format
12
in which you want to save the data source information. For purposes of this example, select Universal data link, and then click Next.
2. Click Finish.
13
The UDL used for this example is: Provider=DB2OLEDB;User ID=DON;Password=don;Initial Catalog=S10D823B;Network Transport Library=TCP;Host CCSID=37;PC Code Page=1252;Network Address=CONTOSO;Network Port=446;Package Collection=CNWIND;Default Schema=CNWIND;Process Binary as Character=False;Units of Work=RUW;DBMS Platform=DB2/AS400;Defer Prepare=False;Rowset Cache Size=0;Persist Security Info=True;Connection Pooling=False;Derive Parameters=False; For more information about the parameters in the preceding data provider string, see the documentation. To view the documentation, click Start, point to All Programs, point to Microsoft BizTalk Adapters for Host Systems, and then click Documentation. The parameters are documented under the MsDb2ConnectionStringBuilder Members.
14
Insert
An insert message contains elements under the after node, but not in the before node.
<InboundRootElementName> <sync> <before/> <after> <Orders id='55' status='Active' /> </after> </sync> </InboundRootElementName>
Delete
A delete message contains elements under the before node, but not in the after node.
<InboundRootElementName> <sync> <before> <Orders id='55' status='Active' /> </before> <after/> </sync> </InboundRootElementName>
15
Update
An update message contains elements under both the before and after nodes; the original value is stored under the before node and the new values are stored under the after node:
<InboundRootElementName> <sync> <before> <Orders id='55' status='Active' /> </before> <after> <Orders id='55' status='Filled' /> </after> </sync> </InboundRootElementName>
Stored Procedures
Updategrams, as defined in SQL Server, do not contain any syntax for executing stored procedures. The updategram syntax that the DB2 adapter uses contains an extension for executing stored procedures with parameters:
<InboundRootElementName> <sync> <StoredProcedure> <AddOrder id=55 status=New/> </StoredProcedure> </sync> </InboundRootElementName>
The updategram for the stored procedure does not contain before or after elements; it only lists the stored procedure to execute as the element name. Parameters are listed as attributes in the order that they should be added to the stored procedure.
SELECT Statements
Updategrams, as defined in SQL Server, do not contain any syntax for executing SELECT statements. The updategram syntax used by the DB2 adapter will contain an extension for executing SELECT statements:
<InboundRootElementName> <sync> <Select>SELECT * FROM ORDERS WHERE STATUS = New</Select> </sync> </InboundRootElementName>
16
The updategram for the SELECT statement does not contain before or after elements. It only lists the SELECT statement to be executed as the element name.
The adapter uses parameters to avoid SQL injection attacks. However, using parameters has a cost in that the data type of the parameters must be discovered for each SQL statement using the MsDb2CommandBuilder.DeriveParameters() method. This uses the Distributed Relational Database Architecture Application Requestor's (DRDA AR) DESCRIBE statement functionality to determine each parameters data type, size, precision, and scale. The adapter converts each string value from the updategram into the parameters type. The command is then executed. DELETE statements work similarly to INSERT statements during conversion, except that the column values are used in a WHERE clause.
<InboundRootElementName> <sync> <before> <Orders id='55' status='Active' /> </before> <after/> </sync> </InboundRootElementName> DELETE FROM Orders WHERE id = ? AND status = ?
UPDATE statements use the before values of the updategram in a WHERE clause and the after values in the SET clause:
<InboundRootElementName>
17 <sync> <before> <Orders id='55' status='Active' /> </before> <after> <Orders id='55' status='Filled' /> </after> </sync> </InboundRootElementName> UPDATE Orders SET id = ?, status = ? WHERE id = ? AND status = ?
The stored procedure extension also uses the MsDb2CommandBuilder.DeriveParameters() method to find the data types of stored procedure parameters for conversion:
<InboundRootElementName> <sync> <StoredProcedure> <AddOrder id=55 status=New/> </StoredProcedure> </sync> </InboundRootElementName> CALL AddOrder (?, ?)
DateTime.TryParse()
TimeSpan.TryParse() Double.TryParse()
18
MsDb2Type
Real Decimal Numeric Binary CharForBit VarBinary VarCharForBit Char WideChar VarChar Graphic VarGraphic VarWideGraphic
Single.TryParse() Decimal.TryParse()
String
When the adapter receives a result set from DB2, the data is converted to an XML message using the column values ToString() method. This uses the current culture to translate to a string. When converting from xsd:dateTime to CLS DateTime, the TryParse method does work successfully.
ResultSet Messages
Result set data is returned to BizTalk using a message that contains a row of data. The schema for this message is similar to an updategram, except that the sync, before, and after elements are removed:
<OutboundRootElementName> <Orders id='55' status='Active' /> </OutboundRootElementName >
The user specifies a single root element name (OutboundRootElementName). The table name is used as the nested element name. Column names are attributes, with each data value as the column name attribute value.
BizTalk Configuration
The example in this section illustrates how to create a BizTalk application to call a stored procedure on the host. In this case the host is an AS/400, but it could be any other DB2
19
platform (such as DB2/Linux or DB2/MVS). This application will also be used to build on for other options. To begin, in the BizTalk Administration console, create a new application. This example uses an application named HISDB2Test1.
3. In the Type text box, select DB2, and then click Configure. 4. On the DB2 Transport Properties dialog box, click the ellipses on the connection string property to bring up the next screen. 5. Select Existing connection string, and then click Browse. At this point, you
20
6. Click Open, and then click Finish. You should be back at the DB2 Transport Properties screen.
21
7. Supply the information for Document Target Namespace and the Response Root Element Name, and then click OK. This example uses DB2Test1 and DB2TestReceive, respectively, for these fields. 8. While still in the Send Port Properties dialog box, to create a filter, click Filters. This is not totally configured yet, but will be later when the receive port is created. Set the BTS.ReceivePortName property value to ReceivePort_DB2Test1Request.
22
23
2. In the Type drop-down menu, select File and then click Configure. 3. In the FILE Transport Properties screen, for the destination folder, browse to a directory on your drive, and for the file name, type DB2Test1Response_ %MessageID%.xml.
24
4. Click OK. 5. In the SendPort_DB2Test1Response - Send Port Properties screen, select Filters. This creates a filter to route the response messages that the DB2 adapter receives. 6. Set the BTS.SPName property value to SendPort_DB2Test1, and then click OK.
25
26
3. Click Receive Locations, click New, and in the Name text box, type Receive Location_DB2Test1Request.
27
4. In the Type drop-down menu, select FILE, and then click Configure. 5. In the FILE Transport Properties screen, for the destination folder, browse to a directory on your drive in which XML files will be placed.
28
29
30
3. Click Next, then click Next again at the wizard welcome screen. You should now be at this screen.
31
4. Click Next again. 5. At the Schema Information screen, type DB2Test1Request for the Request document root element name text box, and then click Next.
32
33
6. On the Statement Type Information screen, select Stored procedure, and then click Next.
The Statement Information screen should show you a list of stored procedures on the database connection that you configured. If no stored procedures are displayed, it is likely that none are present in the database. Contact your database administrator.
34
7. In this example, the first stored procedure is selected. This does not pass any parameters. Rather, it calls the stored procedure, which returns a result set from multiple tables.
35
8. Click Next, and then click Finish. At this point you should have an XSD file in Solution Explorer under references. In this example, it is called MsDB2SendStoredProc.xsd. Note As you create each XSD file, you can rename them (along with the orchestration file) to something more meaningful. The final Solution Explorer window should resemble the following.
36
Testing
Start the BizTalk application (if it has not already been started). Copy (do not move) the XML file into the directory that you created for the receive port. It should disappear from there, and you should receive a response in the out directory that is created off the second send port. In this case, this stored procedure returned the following: <?xml version="1.0" encoding="utf-16" ?> <DB2Test1Receive xmlns="DB2Test1"> <Success> <ResultSets>
37
<Table1 CATID="10001" CATNAME="Condiments" PRODNAME="Lakkalikri" PRODSALES="4767.8000" /> <Table1 CATID="10003" CATNAME="Dairy Products" PRODNAME="Chocolade" PRODSALES="3192.0000" /> <Table1 CATID="10007" CATNAME="Seafood" PRODNAME="Longlife Tofu" PRODSALES="3720.0000" /> <Table1 CATID="10006" CATNAME="Produce" PRODNAME="Alice Mutton" PRODSALES="9399.5000" /> <Table1 CATID="10003" CATNAME="Dairy Products" PRODNAME="Maxilaku" PRODSALES="1440.7500" /> <Table1 CATID="10004" CATNAME="Grains/Cereals" PRODNAME="Mascarpone Fabioli" PRODSALES="8020.0000" /> <Table1 CATID="10004" CATNAME="Grains/Cereals" PRODNAME="Raclette Courdavault" PRODSALES="2345.2500" /> <Table1 CATID="10002" CATNAME="Confections" PRODNAME="Aniseed Syrup" PRODSALES="7600.0000" /> <Table1 CATID="10003" CATNAME="Dairy Products" PRODNAME="Tarte au sucre" PRODSALES="10539.3000" /> <Table1 CATID="10001" CATNAME="Condiments" PRODNAME="Rhnbru Klosterbier" PRODSALES="1038.0000" /> <Table1 CATID="10004" CATNAME="Grains/Cereals" PRODNAME="Queso Cabrales" PRODSALES="10391.2000" /> <Table1 CATID="10002" CATNAME="Confections" PRODNAME="Louisiana Fiery Hot Pepper Sauce" PRODSALES="8571.8500" /> <Table1 CATID="10004" CATNAME="Grains/Cereals" PRODNAME="Gudbrandsdalsost" PRODSALES="4520.0000" /> <Table1 CATID="10002" CATNAME="Confections" PRODNAME="Chef Anton's Gumbo Mix" PRODSALES="5737.6000" /> <Table1 CATID="10003" CATNAME="Dairy Products" PRODNAME="Zaanse koeken" PRODSALES="3079.2000" /> <Table1 CATID="10002" CATNAME="Confections" PRODNAME="Gula Malacca" PRODSALES="11518.4000" /> <Table1 CATID="10003" CATNAME="Dairy Products" PRODNAME="Sir Rodney's Marmalade" PRODSALES="3211.9000" /> <Table1 CATID="10003" CATNAME="Dairy Products" PRODNAME="Valkoinen suklaa" PRODSALES="3240.0000" />
38
<Table1 CATID="10002" CATNAME="Confections" PRODNAME="Northwoods Cranberry Sauce" PRODSALES="9444.0000" /> <Table1 CATID="10002" CATNAME="Confections" PRODNAME="Louisiana Hot Spiced Okra" PRODSALES="9898.0000" /> <Table1 CATID="10005" CATNAME="Meat/Poultry" PRODNAME="Gnocchi di nonna Alice" PRODSALES="8990.4000" /> <Table1 CATID="10007" CATNAME="Seafood" PRODNAME="Manjimup Dried Apples" PRODSALES="2226.2500" /> <Table1 CATID="10007" CATNAME="Seafood" PRODNAME="Tofu" PRODSALES="848.4000" /> <Table1 CATID="10005" CATNAME="Meat/Poultry" PRODNAME="Tunnbrd" PRODSALES="4338.6000" /> <Table1 CATID="10002" CATNAME="Confections" PRODNAME="Vegie-spread" PRODSALES="22673.6000" /> <Table1 CATID="10003" CATNAME="Dairy Products" PRODNAME="Scottish Longbreads" PRODSALES="910.0000" /> <Table1 CATID="10006" CATNAME="Produce" PRODNAME="Perth Pasties" PRODSALES="2142.0000" /> <Table1 CATID="10007" CATNAME="Seafood" PRODNAME="Uncle Bob's Organic Dried Pears" PRODSALES="2500.0000" /> <Table1 CATID="10005" CATNAME="Meat/Poultry" PRODNAME="Singaporean Hokkien Fried Mee" PRODSALES="5151.6000" /> <Table1 CATID="10002" CATNAME="Confections" PRODNAME="Original Frankfurter grne Soe" PRODSALES="7707.6000" /> <Table1 CATID="10001" CATNAME="Condiments" PRODNAME="Chartreuse verte" PRODSALES="51962.2000" /> <Table1 CATID="10003" CATNAME="Dairy Products" PRODNAME="Sir Rodney's Scones" PRODSALES="7776.0000" /> <Table1 CATID="10005" CATNAME="Meat/Poultry" PRODNAME="Wimmers gute Semmelkndel" PRODSALES="7417.1000" /> <Table1 CATID="10001" CATNAME="Condiments" PRODNAME="Cte de Blaye" PRODSALES="676.0000" /> <Table1 CATID="10003" CATNAME="Dairy Products" PRODNAME="Gumbr Gummibrchen" PRODSALES="1926.4000" /> <Table1 CATID="10004" CATNAME="Grains/Cereals" PRODNAME="Gorgonzola Telino" PRODSALES="6554.7000" />
39
<Table1 CATID="10006" CATNAME="Produce" PRODNAME="Tourtire" PRODSALES="10766.8000" /> <Table1 CATID="10004" CATNAME="Grains/Cereals" PRODNAME="Queso Manchego La Pastora" PRODSALES="7425.6000" /> <Table1 CATID="10007" CATNAME="Seafood" PRODNAME="Rssle Sauerkraut" PRODSALES="10974.0000" /> <Table1 CATID="10001" CATNAME="Condiments" PRODNAME="Laughing Lumberjack Lager" PRODSALES="3094.0000" /> <Table1 CATID="10003" CATNAME="Dairy Products" PRODNAME="NuNuCa NuNougat-Creme" PRODSALES="1756.8000" /> <Table1 CATID="10001" CATNAME="Condiments" PRODNAME="Outback Lager" PRODSALES="15156.0000" /> <Table1 CATID="10004" CATNAME="Grains/Cereals" PRODNAME="Flotemysost" PRODSALES="5880.0000" /> <Table1 CATID="10005" CATNAME="Meat/Poultry" PRODNAME="Ravioli Angelo" PRODSALES="34754.8000" /> <Table1 CATID="10002" CATNAME="Confections" PRODNAME="Sirop d'rable" PRODSALES="21794.0000" /> <Table1 CATID="10002" CATNAME="Confections" PRODNAME="Chef Anton's Cajun Seasoning" PRODSALES="1760.0000" /> <Table1 CATID="10002" CATNAME="Confections" PRODNAME="Genen Shouyu" PRODSALES="6561.1500" /> <Table1 CATID="10003" CATNAME="Dairy Products" PRODNAME="Teatime Chocolate Biscuits" PRODSALES="17250.0000" /> <Table1 CATID="10003" CATNAME="Dairy Products" PRODNAME="Pavlova" PRODSALES="1503.5000" /> <Table1 CATID="10004" CATNAME="Grains/Cereals" PRODNAME="Mozzarella di Giovanni" PRODSALES="9034.3000" /> <Table1 CATID="10001" CATNAME="Condiments" PRODNAME="Steeleye Stout" PRODSALES="2240.0000" /> <Table1 CATID="10006" CATNAME="Produce" PRODNAME="Pt chinois" PRODSALES="3415.2500" /> <Table1 CATID="10001" CATNAME="Condiments" PRODNAME="Chang" PRODSALES="5295.6000" /> <Table1 CATID="10003" CATNAME="Dairy Products" PRODNAME="Schoggi Schokolade" PRODSALES="10961.3700" />
40
<Table1 CATID="10004" CATNAME="Grains/Cereals" PRODNAME="Camembert Pierrot" PRODSALES="37917.0000" /> <Table1 CATID="10004" CATNAME="Grains/Cereals" PRODNAME="Geitost" PRODSALES="3136.0000" /> <Table1 CATID="10001" CATNAME="Condiments" PRODNAME="Sasquatch Ale" PRODSALES="814.5000" /> <Table1 CATID="10001" CATNAME="Condiments" PRODNAME="Guaran Fantstica" PRODSALES="2392.2000" /> <Table1 CATID="10006" CATNAME="Produce" PRODNAME="Thringer Rostbratwurst" PRODSALES="14610.0000" /> <Table1 CATID="10006" CATNAME="Produce" PRODNAME="Mishi Kobe Niku" PRODSALES="4560.0000" /> <Table1 CATID="10005" CATNAME="Meat/Poultry" PRODNAME="Gustaf's Knckebrd" PRODSALES="5686.0000" /> <Table1 CATID="10005" CATNAME="Meat/Poultry" PRODNAME="Filo Mix" PRODSALES="26065.4000" /> <Table1 CATID="10002" CATNAME="Confections" PRODNAME="Grandma's Boysenberry Spread" PRODSALES="405.6500" /> <Table1 CATID="10001" CATNAME="Condiments" PRODNAME="Ipoh Coffee" PRODSALES="6006.0000" /> </ResultSets> </Success> </DB2Test1Receive>
41
OUT O_ORDMONTH CHAR(3) , OUT O_QTY SMALLINT , OUT O_AMOUNT DECIMAL(9, 2) ) DYNAMIC RESULT SETS 2 LANGUAGE SQL SPECIFIC CNWIND.SP_INOUTSALES NOT DETERMINISTIC MODIFIES SQL DATA CALLED ON NULL INPUT SET OPTION ALWBLK = *ALLREAD , ALWCPYDTA = *OPTIMIZE , COMMIT = *NONE , DECRESULT = (31, 31, 00) , DFTRDBCOL = *NONE , DYNDFTCOL = *NO , DYNUSRPRF = *USER , SRTSEQ = *HEX BEGIN DECLARE C1 CURSOR FOR SELECT PRODID , ORDYEAR , ORDMONTH , QTY , AMOUNT FROM CNWIND . SALES WHERE PRODID = I_PRODID ; DECLARE C2 CURSOR WITH RETURN FOR SELECT * FROM CNWIND . SALES ; INSERT INTO CNWIND . SALES ( PRODID , ORDYEAR , ORDMONTH , QTY , AMOUNT ) VALUES ( I_PRODID , I_ORDYEAR , I_ORDMONTH , I_QTY , I_AMOUNT ) ; OPEN C1 ; OPEN C2 ; FETCH C1 INTO O_PRODID , O_ORDYEAR , O_ORDMONTH , O_QTY , O_AMOUNT ; END ; This stored procedure contains a total of ten parameters: 5 IN, 5 OUT. When creating the schema in Visual Studio, make sure to select ALL values. When you first look at a stored procedure in the wizard, the dialog box looks similar to this.
42
As you select the parameters, the results at the bottom of the page will be updated. The XML file that is created from the XSD file is similar to this:
<ns0:DB2Test2Request xmlns:ns0="DB2Test2"> <sync> <StoredProcedure> <SP_INOUTSALES I_PRODID="10" I_ORDYEAR="I_ORDYEAR_1" I_ORDMONTH="I_ORDMONTH_2" I_QTY="10" I_AMOUNT="10.4" O_PRODID="10" O_ORDYEAR="O_ORDYEAR_6" O_ORDMONTH="O_ORDMONTH_7" O_QTY="10" O_AMOUNT="10.4" /> </StoredProcedure> </sync> </ns0:DB2Test2Request>
Obviously this XML file needs changing because the schema generated by Visual Studio does not take into account the possibility that some fields might be a char(4), another a char(3), and so on. Therefore, after modifying it to meet your scenario, you end up with this. Notice that the output parameters are blank (null), but present and quoted. This is required.
<ns0:DB2Test2Request xmlns:ns0="DB2Test2"> <sync> <StoredProcedure> <SP_INOUTSALES
43 I_PRODID="10061" I_ORDYEAR="2006" I_ORDMONTH="FEB" I_QTY="1000" I_AMOUNT="7000.00" O_PRODID="" O_ORDYEAR="" O_ORDMONTH="" O_QTY="" O_AMOUNT="" /> </StoredProcedure> </sync> </ns0:DB2Test2Request>
Note You do not have to populate all the parameters, but they all need to be present. After submitting this XML file to BizTalk, you should receive a response file similar to this: <?xml version="1.0" encoding="utf-16" ?> <DB2Test1Receive xmlns="DB2Test1"> <Success> <SP_INOUTSALES I_PRODID="" I_ORDYEAR="" I_ORDMONTH="" I_QTY="" I_AMOUNT="" O_PRODID="10061" O_ORDYEAR="2006" O_ORDMONTH="FEB" O_QTY="1000" O_AMOUNT="7000.00" /> <ResultSets> <Table1 PRODID="10051" ORDYEAR="2007" ORDMONTH="JAN" QTY="10" AMOUNT="70.00" /> <Table1 PRODID="10052" ORDYEAR="2007" ORDMONTH="JAN" QTY="10" AMOUNT="70.00" /> <Table1 PRODID="10053" ORDYEAR="2007" ORDMONTH="JAN" QTY="10" AMOUNT="70.00" /> <Table1 PRODID="10054" ORDYEAR="2007" ORDMONTH="JAN" QTY="10" AMOUNT="70.00" /> <Table1 PRODID="10055" ORDYEAR="2007" ORDMONTH="JAN" QTY="10" AMOUNT="70.00" /> <Table1 PRODID="10056" ORDYEAR="2007" ORDMONTH="JAN" QTY="10" AMOUNT="70.00" /> <Table1 PRODID="10057" ORDYEAR="2007" ORDMONTH="JAN" QTY="10" AMOUNT="70.00" /> <Table1 PRODID="10058" ORDYEAR="2007" ORDMONTH="JAN" QTY="10" AMOUNT="70.00" />
44
<Table1 PRODID="10060" ORDYEAR="2006" ORDMONTH="FEB" QTY="100" AMOUNT="700.00" /> <Table1 PRODID="10061" ORDYEAR="2006" ORDMONTH="FEB" QTY="1000" AMOUNT="7000.00" /> </ResultSets> </Success> </DB2Test1Receive> In the first return (after the <Success> tag, the input parameters are now set to null (""), and the output parameters are now populated. The fetch statement in the stored procedure returns these values. The result set shows all values that are currently in the table as specified in the stored procedure (select * from).
45
3. In the Statement Information screen, in Select the type of updategram, click Insert, select a table, click Check all, click Next, and then click Finish.
46
4. Right-click the generated XSD file, generate an instance, and then save the XML file to preserve it. When you first open the file in Visual Studio it should look similar to this:
<ns0:DB2Test3Request xmlns:ns0="DB2Test3"> <sync> <after> <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" </after> <after> <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" </after> <after> <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" </after> </sync> </ns0:DB2Test3Request>
47
It is also possible to modify the file to include an <after> statement such as:
<ns0:DB2Test3Request xmlns:ns0="DB2Test3"> <sync> <after> <AREAS AREAID="28105" AREADESC="Matthews" REGIONID="101" /> <AREAS AREAID="28277" AREADESC="Charlotte" REGIONID="101" /> <AREAS AREAID="28201" AREADESC="Charlotte" REGIONID="101" /> <AREAS AREAID="27408" AREADESC="Greensboro" REGIONID="101" /> <AREAS AREAID="27608" AREADESC="Raleigh" REGIONID="101" /> <AREAS AREAID="27104" AREADESC="Winston Salem" REGIONID="101" /> </after> </sync> </ns0:DB2Test3Request>
5. Copy this file into your directory used previously. When the message has been processed, you should have an XML file similar to this:
<?xml version="1.0" encoding="utf-16"?> <DB2Test1Receive xmlns="DB2Test1"> <Success> <RowsAffected>1</RowsAffected> </Success> <Success> <RowsAffected>1</RowsAffected> </Success> <Success> <RowsAffected>1</RowsAffected> </Success> <Success> <RowsAffected>1</RowsAffected> </Success> <Success> <RowsAffected>1</RowsAffected>
49
click Update, select a table, click Check all, click Next, and then click Finish.
4. After doing this, right-click the generated XSD file, generate an instance, then save the XML file to preserve it. When you first open the file in Visual Studio, it should look similar to this:
<ns0:DB2Test4Request xmlns:ns0="DB2Test4"> <sync> <before> <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" </before> <before> <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" </before> <before> <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" </before> <after>
50 <AREAS AREAID="AREAID_0" <AREAS AREAID="AREAID_0" <AREAS AREAID="AREAID_0" </after> <after> <AREAS AREAID="AREAID_0" <AREAS AREAID="AREAID_0" <AREAS AREAID="AREAID_0" </after> <after> <AREAS AREAID="AREAID_0" <AREAS AREAID="AREAID_0" <AREAS AREAID="AREAID_0" </after> </sync> </ns0:DB2Test4Request> AREADESC="AREADESC_1" REGIONID="10" /> AREADESC="AREADESC_1" REGIONID="10" /> AREADESC="AREADESC_1" REGIONID="10" />
As stated previously, edit the file to meet your scenario. The previous test (inserting rows) contains a deliberate mistake in one of the inserts (the line containing <AREAS AREAID="28201" AREADESC="Charlotte" REGIONID="101" />). This should have been 28226 instead of 28201 for the AREAID. To make sure only the 28201 entry is updated, the XML file is modified as such:
<ns0:DB2Test4Request xmlns:ns0="DB2Test4"> <sync> <before> <AREAS AREAID="28201" AREADESC="Charlotte" REGIONID="101" /> </before> <after> <AREAS AREAID="28226" /> </after> </sync> </ns0:DB2Test4Request>
After submitting this to the send port, you should receive the following: <?xml version="1.0" encoding="utf-16"?><DB2Test1Receive xmlns="DB2Test1"><Success><RowsAffected>1</RowsAffected></Success></ DB2Test1Receive> Looking at the database in SQL Server verifies that the update took place: EXEC ( 'SELECT * FROM CNWIND.AREAS') AT CONTOSOCNWIND; The preceding query returned
51
27104Winston Salem101 27608Raleigh101 27408Greensboro101 28226Charlotte101 28277Charlotte101 28105Matthews101 In this particular table, the AREAID is a unique field, so it would have been possible to just specify the AREAID in the before section of the updategram.
52
3. In the Statement Information screen, in Select the type of updategram, click Delete, select a table, click Check all, click Next, and then click Finish
53
4. Right-click the generated XSD file, generate an instance, then save the XML file to preserve it. 5. Open the XML file. It should look similar to this.
<ns0:DB2Test5 xmlns:ns0="DB2Test5"> <sync> <before> <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" </before> <before> <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" </before> <before> <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" <AREAS AREAID="AREAID_0" AREADESC="AREADESC_1" </before> </sync> </ns0:DB2Test5>
54
Note There is a deliberate mistake in the preceding XML file, which will be corrected in a later exercise. <?xml version="1.0" encoding="utf-16" ?> <DB2Test1Receive xmlns="DB2Test1"> <Success> <RowsAffected>1</RowsAffected> </Success> <Success> <RowsAffected>1</RowsAffected> </Success> <Success> <RowsAffected>1</RowsAffected> </Success> <Success> <RowsAffected>0</RowsAffected> </Success> <Success> <RowsAffected>1</RowsAffected> </Success> <Success>
55
<RowsAffected>1</RowsAffected> </Success> </DB2Test1Receive> Notice in the preceding, the failure -> <RowsAffected>0</RowsAffected>. This is because an AREAID of 28201 was submitted, which was changed in the previous example. Therefore, this row was not deleted. However, all other rows were deleted successfully.
56
3. Click Finish. There are no other dialog boxes with this option. 4. Generate the XML file as previously, and bring it up in Visual Studio. The original should look similar to this:
<ns0:DB2Test6Request xmlns:ns0="DB2Test6"> <sync> <Select>Select_0</Select> </sync> </ns0:DB2Test6Request>
Once you have saved the file, submit this as you have done previously. The output should be similar to this: <?xml version="1.0" encoding="utf-16" ?> <DB2Test1Receive xmlns="DB2Test1"> <Success> <ResultSets> <AREAS AREAID="01581" AREADESC="Westboro" REGIONID="101" /> <AREAS AREAID="01730" AREADESC="Bedford" REGIONID="101" /> <AREAS AREAID="01833" AREADESC="Georgetow" REGIONID="101" /> <AREAS AREAID="02116" AREADESC="Boston" REGIONID="101" /> <AREAS AREAID="02139" AREADESC="Cambridge" REGIONID="101" /> <AREAS AREAID="02184" AREADESC="Braintree" REGIONID="101" /> <AREAS AREAID="02903" AREADESC="Providence" REGIONID="101" /> ... ... ... <AREAS AREAID="98052" AREADESC="Redmond" REGIONID="102" /> <AREAS AREAID="98104" AREADESC="Seattle" REGIONID="102" /> <AREAS AREAID="28226" AREADESC="Charlotte" REGIONID="101" /> </ResultSets> </Success>
57
</DB2Test1Receive> The 28226, Charlotte values are still present because this row has not been deleted at this time.
ADDENDUM
Data Flow Charts
All the previous tests used the three ports configured in the "BizTalk Configuration" section (2 send ports, 1 receive port). The flows are the same for all the tests.
58
59
60
61
62
63
64
OUT O_RETURKOD CHAR(4) , INOUT IO_SQLCODE INTEGER , OUT O_MEDD CHAR(7) , OUT O_MEDDTEXT CHAR(70) , OUT O_TERMNAMN CHAR(16) , IN I_AVISERINGSKANAL CHAR(8) , IN I_BENAMNING CHAR(35) , INOUT IO_REGDATTID CHAR(26) , INOUT IO_REGUSERID CHAR(8) ) LANGUAGE SQL SPECIFIC DON.SP_MANYPARAMS NOT DETERMINISTIC MODIFIES SQL DATA CALLED ON NULL INPUT SET OPTION ALWBLK = *ALLREAD , ALWCPYDTA = *OPTIMIZE , COMMIT = *NONE , DECRESULT = (31, 31, 00) , DFTRDBCOL = *NONE , DYNDFTCOL = *NO , DYNUSRPRF = *USER P1 : BEGIN SET O_RETURKOD = 'BOB1' ; SET IO_SQLCODE = 3 ; SET O_MEDD = 'CHARLES' ; SET O_TERMNAMN = '16 CHARACTERSOUT' ; SET IO_REGDATTID = '25 CHARACTERS OUT OF THIS' ; SET IO_REGUSERID = 'DON' ; END P1 ;
Test Runs
Five tests were performed as follows:
65
Test 1 In this test, the original XML that was generated was modified as below to match the input requirements for this stored procedure:
<ns0:HISStoredProcRequest xmlns:ns0="HISStoredProc"> <sync> <StoredProcedure> <SP_MANYPARAMS10 I_FUNKTION="R" O_RETURKOD="" IO_SQLCODE="3" O_MEDD="" O_MEDDTEXT="" O_TERMNAMN="" I_AVISERINGSKANAL="BREVMOT" I_BENAMNING="" IO_REGDATTID="" IO_REGUSERID="" /> </StoredProcedure> </sync> </ns0:HISStoredProcRequest>
This worked without any problems. Test 2 In this test, the the first and second parameters were switched:
<ns0:HISStoredProcRequest xmlns:ns0="HISStoredProc"> <sync> <StoredProcedure> <SP_MANYPARAMS10 O_RETURKOD="" I_FUNKTION="R" IO_SQLCODE="3" O_MEDD="" O_MEDDTEXT="" O_TERMNAMN="" I_AVISERINGSKANAL="BREVMOT" I_BENAMNING="" IO_REGDATTID="" IO_REGUSERID="" /> </StoredProcedure> </sync> </ns0:HISStoredProcRequest>
This seems to work just fine. Test 3 In this test, the second parameter was deleted, so only nine are being passed to the stored procedure:
<ns0:HISStoredProcRequest xmlns:ns0="HISStoredProc"> <sync> <StoredProcedure> <SP_MANYPARAMS10 I_FUNKTION="R" IO_SQLCODE="3" O_MEDD="" O_MEDDTEXT="" O_TERMNAMN="" I_AVISERINGSKANAL="BREVMOT" I_BENAMNING="" IO_REGDATTID="" IO_REGUSERID="" /> </StoredProcedure> </sync> </ns0:HISStoredProcRequest>
This fails with a BizTalk Server 2006 Event ID 5743: The adapter failed to transmit message going to send port "SendPort1_StoredProcUpdate" with URL "DB2://DB282:50000/PSS/DON". It will be
66
retransmitted after the retry interval specified for this Send Port. Details:"Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index". Test 4 In this test, the ten parameters were mixed up, so that they were in the wrong order in various places.
<ns0:HISStoredProcRequest xmlns:ns0="HISStoredProc"> <sync> <StoredProcedure> <SP_MANYPARAMS10 O_RETURKOD="" IO_SQLCODE="3" I_FUNKTION="R" O_MEDDTEXT="" O_MEDD="" O_TERMNAMN="" I_BENAMNING="" IO_REGDATTID="" I_AVISERINGSKANAL="BREVMOT" IO_REGUSERID="" /> </StoredProcedure> </sync> </ns0:HISStoredProcRequest>
This fails with the following error: BizTalk Server 2006 Event ID 5743: The adapter failed to transmit message going to send port "SendPort1_StoredProcUpdate" with URL "DB2://DB282:50000/PSS/DON". It will be retransmitted after the retry interval specified for this Send Port. Details:"The parameter value for parameter 2 could not be converted to a native data type. Parameter Name: I_FUNKTION, Data Type: R, Value : Int". Test 5 The XML file was changed as follows:
<ns0:HISStoredProcRequest xmlns:ns0="HISStoredProc"> <sync> <StoredProcedure> <SP_MANYPARAMS10 ONE="R" TWO="" THREE="3" FOUR="" FIVE="" SIX="" SEVEN="BREVMOT"
The XML file was placed in the receive port location. The following is what was received in the outbox, which indicates everything worked as expected. <?xml version="1.0" encoding="utf-16" ?> <HISStoredProcResponse xmlns="HISStoredProc"> <Success> <SP_MANYPARAMS10 I_FUNKTION="" O_RETURKOD="BOB1" IO_SQLCODE="3" O_MEDD="CHARLES" O_MEDDTEXT="70 CHARACTERS NOT!" O_TERMNAMN="16 CHARACTERSOUT" I_AVISERINGSKANAL="" I_BENAMNING="" IO_REGDATTID="25 CHARACTERS OUT OF THIS" IO_REGUSERID="DON" /> <ResultSets /> </Success> </HISStoredProcResponse>
68
However, in the XML file, a NULL (), a 3 (read as a character), and an R were sent. The R cannot be converted to an integer, so it fails. Test 5 shows that the input XML parameter names do not matter, as long as you have the right number of parameters and they are in the correct order. This is because it is a parameterized query, so the offset is what matters.
Conclusion
This document addressed using send ports to submit commands to the DB2 database You used the Data Access Tool to create a data connection. You then configured BizTalk Server and Visual Studio to use the BizTalk Adapter for DB2, and conducted tests in various scenarios. For more information about the BizTalk Adapter for DB2, see http://go.microsoft.com/fwlink/?LinkId=91515.
Copyright
The information contained in this document represents the current view of Microsoft Corporation on the issues discussed as of the date of publication. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information presented after the date of publication. This White Paper is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS DOCUMENT. Complying with all applicable copyright laws is the responsibility of the user. Without limiting the rights under copyright, no part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of Microsoft Corporation. Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property. Unless otherwise noted, the companies, organizations, products, domain names, e-mail addresses, logos, people, places, and events depicted in examples herein are fictitious. No association with any real company, organization, product, domain name, e-mail address, logo, person, place, or event is intended or should be inferred.
69
2007 Microsoft Corporation. All rights reserved. Microsoft, BizTalk, Visual Studio, and Windows are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries. All other trademarks are property of their respective owners.