Insert Master-Detail data structure on SQL Server in a single transaction using BizTalk Server

 

In the last days, we need to enter data structures of master-detail type in SQL Server inside a single transaction.

Initially we tried to invoke the insertion of the header and the insertion of the details using two send shapes inside an atomic scope. Soon we realized that BizTalk activates the DTC only using WCF WS-http.

So we thought to use the composite operation technic that so far we only used to invoke n times the same stored procedure and in particular to insert batch of records.

Microsoft’s documentation is very clear in regard and illustrates different possibilities in using this technique (http://msdn.microsoft.com/en-us/library/dd788136.aspx).

However, since there is nothing on the Internet that describes our specific case, or at least we did not find any example, we decided to illustrate a simple case that I hope will be useful.

In the following paragraphs, we show the steps to prepare the database, create the BizTalk project and deploy the example.

Database setup

For brevity, the used data structure is very simple and is composed just from two table in master-detail form.

Following the data diagram.

clip_image002

Once created the data structure we have created two stored procedures for entering data in the two tables.

Below is the script to create the database, tables and stored procedures.

USE [master] 
GO 

CREATE DATABASE [MyDatabase] 
GO 

USE [MyDatabase] 
GO 

CREATE TABLE [dbo].[Header]
( 
    [idHeader] [uniqueidentifier] NOT NULL, 
    [headerAttribute1] [varchar](50) NULL, 
    [transactionDate] [datetime] NULL, 

    CONSTRAINT [PK_Header] PRIMARY KEY CLUSTERED 
    ( 
    [idHeader] ASC 
    ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 
GO 

CREATE TABLE [dbo].[Detail]
( 
    [idDetail] [int] IDENTITY(1,1) NOT NULL, 
    [idHeader] [uniqueidentifier] NOT NULL, 
    [detailAttribute1] [varchar](50) NULL, 

    CONSTRAINT [PK_Detail] PRIMARY KEY CLUSTERED 
    ( 
    [idDetail] ASC 
    ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 
GO 

CREATE PROCEDURE [dbo].[insertHeader] 
    @idHeader CHAR(36), 
    @headerAttribute1 VARCHAR(50) 
AS 
BEGIN 

    INSERT INTO Header 
    ( 
        idHeader, 
        headerAttribute1, 
        transactionDate 
    ) 
    VALUES 
    ( 
        @idHeader, 
        @headerAttribute1, 
        GETDATE() 
    ) 

END 
GO 

CREATE PROCEDURE [dbo].[insertDetail] 
    @idHeader CHAR(36), 
    @detailAttribute1 VARCHAR(50) 
AS 
BEGIN 

    INSERT INTO Detail 
    ( 
        idHeader, 
        detailAttribute1 
    ) 
    VALUES 
    ( 
        @idHeader, 
        @detailAttribute1 
    ) 

END 
GO 

ALTER TABLE [dbo].[Detail] WITH CHECK ADD CONSTRAINT [FK_Detail_Header] FOREIGN KEY([idHeader]) 
REFERENCES [dbo].[Header] ([idHeader]) 
ON DELETE CASCADE 
GO 

ALTER TABLE [dbo].[Detail] CHECK CONSTRAINT [FK_Detail_Header] 
GO

 

BizTalk Project

Create a new BizTalk project and generate the schema for the stored procedures. The following figure shows the most important step during generation.

clip_image003

Once schema is generated, you should have the following items inside the project.

clip_image004

Now we have created a schema for composite operation.

clip_image006

In the property of the schema, you have to import the stored procedure schema as shown in the follow.

clip_image007

Select the schema generated in the previous step.

clip_image008

Now create two root element that, as from specific, you have to name Request and RequestResponse.

clip_image009

In the Request root element, create a child record for the input of Header stored procedure.

clip_image011

In the Data Structure Type specify “InsertHeader”.

clip_image013

Repeat the previous step for the Detail, the Header response and Detail response. You should obtain the following schema.

clip_image014

You must then specify the min occurs and max occurs properties.

clip_image016

Now you have to create an input schema. Following you can find a very simple example that we used.

<?xml version="1.0" encoding="utf-16"?> 
<xs:schema xmlns="http://CompositeAdvancedOperations.schInput" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" targetNamespace="http://CompositeAdvancedOperations.schInput" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="MyEntity"> 
        <xs:complexType> 
            <xs:sequence> 
                <xs:element name="entityId" type="xs:string" /> 
                <xs:element name="headerAttribute1" type="xs:string" /> 
                <xs:element minOccurs="0" maxOccurs="unbounded" name="entityDetail"> 
                    <xs:complexType> 
                        <xs:sequence> 
                            <xs:element name="detailAttribute1" type="xs:string" /> 
                        </xs:sequence> 
                    </xs:complexType> 
                </xs:element> 
            </xs:sequence> 
        </xs:complexType> 
    </xs:element> 
</xs:schema>

 

Create a map for the transformation from input schema to insert operation.

clip_image018

Following the simple map.

clip_image020

Now generate an input XML instance in order to test the solution.

<ns0:MyEntity xmlns:ns0="http://CompositeAdvancedOperations.schInput"> 
    <entityId>2F9509A4-5CDF-4C15-8B59-ECD7F9B8E5F6</entityId> 
    <headerAttribute1>HEAD</headerAttribute1> 
    <entityDetail> 
        <detailAttribute1>A</detailAttribute1> 
    </entityDetail> 
    <entityDetail> 
        <detailAttribute1>B</detailAttribute1> 
    </entityDetail> 
    <entityDetail> 
        <detailAttribute1>C</detailAttribute1> 
    </entityDetail> 
</ns0:MyEntity>

 

Finally create the orchestration.

clip_image022

I think should be simple to imagine the integration flow.

clip_image024

BizTalk Administrative Task

From the BizTalk Administration interface, you have to create a new application and create the needed ports.

You can create the send port that calls the stored procedure simply by using the binding file that visual studio has generated.

As from specific, remember to add the action inside the send port from the composite operation.

clip_image025

In order to manage the error inside the orchestration you can modify the following parameters.

clip_image027

After, you have to create the receive port and location manually.

Polling Oracle Database Using Stored Procedures, Functions, or Packaged Procedures and Functions

 

This document shows the step to configure a polling operation using Oracle Function or Packaged Procedure and Functions.

Please refer to MSD article for additional detail (http://msdn.microsoft.com/en-us/library/dd788064.aspx).

Procedure

Open Visual Studio, create a new BizTalk project and generate the polling schema using Consume Adapter Service wizard.

clip_image002

Click on “Configure”.

clip_image003

Specify a PollingId as Polling Unique Identifier.

clip_image004

Leave the following form with default settings.

clip_image005

Connect to the database, select “Service (inbound operation)” and choose the Oracle function.

clip_image006

Edit binding file in order to set the following properties:

1. Receive port name

2. Receive location name

clip_image007

3. If BizTalk host is Trusted you should set host trusted equal to true.

clip_image008

From BizTalk Administration import the generated binding file.

clip_image009

If needed, rename the receive port and enable routing for failed messages.

clip_image011

Rename the receive location.

clip_image012

Click on Configure and set the following properties:

PolledDataAvailableStatement

In this example, we use the Oracle function CCM_ADT_PKG.CCM_COUNT, which require a string parameter.

SELECT CCM_ADT_PKG.CCM_COUNT('A02') FROM DUAL

PollingAction

From Visual Studio open the schema “schOracleA02CCM.PollingPackage.CCM_ADT_PKG.xsd” and find for the “action” element.

clip_image013

Copy the url “http://Microsoft.LobServices.OracleDB/2007/03/CCM/PollingPackage/CCM_ADT_PKG/CCM_BIZTALK_ADT_2” and set the PollingAction property.

PollingStatement

From visual studio, generate a XML instance for the schema “schOracleA02CCM.Package.CCM_ADT_PKG.xsd”.

clip_image014

Modify XML content setting up the right parameters.

<ns0:CCM_BIZTALK_ADT_2 xmlns:ns0="http://Microsoft.LobServices.OracleDB/2007/03/CCM/Package/CCM_ADT_PKG">
    <ns0:TIPO_MESSAGGIO>A02</ns0:TIPO_MESSAGGIO>
    <ns0:FL_ELABORAZIONE>0</ns0:FL_ELABORAZIONE>
</ns0:CCM_BIZTALK_ADT_2>

Set Polling Interval to 30 seconds and user name and password.

clip_image015