Alright, now that the New Zealand Tech Ed is done and dusted people around here are back at blogging, including me.
I thought I’d start with one that’s been on my list for a while: how to make multiple calls to the same stored procedure using the SQL Adapter without having to use a loop shape.
No matter how much you use BizTalk – you’re always learning a new trick. This one comes courtesy of some fellow BizTalk developers here at work – Mark Brimble, Capree Lim and Colin Dijkgraaf.
Say I have this table inside my SQL Server MyTestDB database:
CREATE TABLE [dbo].[tbMyTestTable]
([id] [int] IDENTITY(1,1) NOT NULL,
[Code] [nchar] (5) NOT NULL,
[Name] [nchar] (30) NOT NULL,
[Type] [nchar] (10) NOT NULL,
[PartnerID] [int] NOT NULL,
CONSTRAINT [PK_tbMyTestTable] PRIMARY KEY CLUSTERED
([id] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
And I have this stored procedure on the same database:
CREATE
PROCEDURE [dbo].[myTestSProc]
@Code nchar(5) ,@Name nchar(30), @Type nchar(10), @PartnerID int
AS BEGIN
SET NOCOUNT ON;
IF EXISTS(Select Code from tbMyTestTable tb where Code= @Code)
UPDATE [MyTestDB].[dbo].[tbMyTestTable]
SET [Code] = @Code, [Name] = @Name, [Type] = @Type, [PartnerID] = @PartnerID
WHERE [Code] = @Code
ELSE
INSERT INTO [MyTestDB].[dbo].[tbMyTestTable]
([Code], [Name], [Type], [PartnerID])
VALUES (@Code, @Name, @Type, @PartnerID)
END
As you can see, the stored procedure will insert a new row in case the code doesn’t already exist, otherwise it will update the row with that code. From this I used the trusty “Add Generated Items” -> “Add Adapter Metadata” to create the schema for that stored procedure. It looks like this:

Now, here is the trick: on the properties of the myTestSProc node (the node with the name of your stored procedure) I changed the Max Occurs setting to unbounded. This will make the schema allow us to repeat that row of XML as many times as we want.
I then created a flat file schema with those same elements:

And, of course, a straight map between the two:

And for simplicity I created an orchestration to manage it all (although it could and should all have been done via messaging with no need for an orchestration):

Notice how there is no looping shape in the orchestration – it is doing a straight map. So if my (weird) test flat file looks like:
AAA,First Code,Blue,1
AAB,Second Code,Blue,2
AAC,Third Code,Blue,3
AAD,Fourth Code,Green,4
AAE,Fifth Code,Red,5
AAF,Sixth Code,Green,6
AAG,Seventh Code,Green,7
AAH,Eight Code,Red,8
AAI,Ninth Code,Yellow,9
AAA,Tenth Code,Green,10
It gets mapped to the following XML which is then sent to the SQL Adapter:
<ns0:SQLInsertCodeReq
xmlns:ns0=“http://MyBizTalkProject/SQLInsert“>
<ns0:myTestSProc Code=“AAA” Name=“First Code” Type=“Blue” PartnerID=“1“></ns0:myTestSProc>
<ns0:myTestSProc Code=“AAB” Name=“Second Code” Type=“Blue” PartnerID=“2“></ns0:myTestSProc>
<ns0:myTestSProc Code=“AAC” Name=“Third Code” Type=“Blue” PartnerID=“3“></ns0:myTestSProc>
<ns0:myTestSProc Code=“AAD” Name=“Fourth Code” Type=“Green” PartnerID=“4“></ns0:myTestSProc>
<ns0:myTestSProc Code=“AAE” Name=“Fifth Code” Type=“Red” PartnerID=“5“></ns0:myTestSProc>
<ns0:myTestSProc Code=“AAF” Name=“Sixth Code” Type=“Green” PartnerID=“6“></ns0:myTestSProc>
<ns0:myTestSProc Code=“AAG” Name=“Seventh Code” Type=“Green” PartnerID=“7“></ns0:myTestSProc>
<ns0:myTestSProc Code=“AAH” Name=“Eight Code” Type=“Red” PartnerID=“8“></ns0:myTestSProc>
<ns0:myTestSProc Code=“AAI” Name=“Ninth Code” Type=“Yellow” PartnerID=“9“></ns0:myTestSProc>
<ns0:myTestSProc Code=“AAA” Name=“Tenth Code” Type=“Green” PartnerID=“10“></ns0:myTestSProc>
</ns0:SQLInsertCodeReq>
So after configuring all the ports and binding everything as per normal SQL Adapter, we end up with nine rows in the table. Nine rows? Hah! Notice that the code on the last line is ‘AAA’, so the stored procedure just updates the row that was inserted first.
This is pretty powerful: all the calls to the stored procedure get wrapped around the same DTC transaction. If one of them fails (which I tested by changing a PartnerID to a string) the whole thing gets rolled back. We have something similar in production uploading a file with 30 thousand records in less than a minute as well.
Hope it’s useful to other BizTalkers.
–Thiago Almeida
RSS


Good Trick Thiago!
Comment by Nino Crudele — September 9, 2008 @ 7:13 pm
damn … that’s most definitely useful info. will make sure to make use of this in future.
Comment by Ryan CrawCour — September 9, 2008 @ 10:49 pm
Hi, please send me the sample of this.
Comment by Renu — August 3, 2009 @ 9:03 pm
Hi Renu,
You can download the BizTalk sample solution from here:
http://www.acsug.co.nz/files/Downloads/SQLMultipleSPROCCalls.aspx
Regards,
Thiago
Comment by Thiago Almeida — August 10, 2009 @ 8:27 am
For extra bonus points, let’s see your compensation routine for this!
Comment by Lucas Vogel — September 10, 2008 @ 1:32 am
This is so damn easy it makes me cry that I did not figure this out sooner! This is a huge performance boost for some of my solutions!!!
Comment by Ben — September 10, 2008 @ 2:20 am
Oh, and thanks for posting this!
Comment by Ben — September 10, 2008 @ 2:20 am
Thanks all! One thing I forgot to mention is that this will not work if your stored procedure is returning XML back to the orchestration. The new “WCF LOB Adapter SDK”-based SQL Adapter will allow that.
Comment by Thiago Almeida — September 10, 2008 @ 8:33 am
Hi Thiago,
Please send me the sample running for this application. As I am pretty new in Biztalk so not able to understand this. Although I tried to make the application like this but its just fetching the first row only and passing the same to database. But its not transferring the other rows.
Please help me and send me the sample. It is too urgent to save my job.
Regards.
Rimps
Comment by Rimps — August 7, 2009 @ 4:38 pm
Hi Rimps,
You can download the BizTalk sample solution from here:
http://www.acsug.co.nz/files/Downloads/SQLMultipleSPROCCalls.aspx
You probably forgot to change the stored procedure schema or the flat file schema node to unbounded, that’s why you only get one line inserted.
Regards,
Thiago
Comment by Thiago Almeida — August 10, 2009 @ 8:27 am
Nice trick, I tried it out on my BizTalk 2006 R2 VPC and worked like a charm.
Comment by Steef-Jan — September 12, 2008 @ 6:39 am
Excellent tip.. it will certainly boost performance…
Comment by Marshal — September 14, 2008 @ 3:12 am
[...] Finally if you are de-batching just so you can submit your messages to a SQL send port one by one don’t bother. See this article by Multiple Stored Procedure Calls using the BizTalk SQL Adapter without a loop shape « Connected Thou… [...]
Pingback by Tricks with Schemas Part 1: De-batching from a SQL Receive Port « Connected Pawns — September 25, 2008 @ 1:18 pm
Hi all!
Nice site!
Bye
Comment by oblilaitatips — October 2, 2008 @ 1:59 am
Hi Thiago Almeida! Do you know something about this in Oracle Adapter? Can be done? Because we have something like this in the Metadata generated Schema:
(…)
So… as the first element cannot be multiple, I guess there is no other option than the loop.
Best regards and congrats for the BizTalk/SQL tip
Daniel Santana
Comment by Daniel Santana — December 9, 2008 @ 9:08 am
Hummmm…. problem with the posted schema… Lets try again…
[?xml version="1.0"?]
[xsd:schema xmlns:PKG_ATRIBUFUN_IN="http://schemas.microsoft.com/[OracleDb://OracleDB_SADBR_FPW/SADBR_FPW/Procedures/PKG_ATRIBUFUN_INSERT]” elementFormDefault=”qualified” targetNamespace=”http://schemas.microsoft.com/[OracleDb://OracleDB_SADBR_FPW/SADBR_FPW/Procedures/PKG_ATRIBUFUN_INSERT]” xmlns:xsd=”http://www.w3.org/2001/XMLSchema”]
[xsd:element name="SP_ATRIBUFUN_INSERT"]
[xsd:complexType]
Comment by Daniel Santana — December 9, 2008 @ 9:09 am
Hi Daniel,
Sorry, I haven’t done this with the oracle adapter. With the SQL adapter the adapter understands the multiple lines in the schema. But like you said – the root element can’t repeat so doesn’t look like it’ll work like with the SQL adapter.
Comment by Thiago Almeida — December 9, 2008 @ 10:58 am
[...] with BizTalk solutions: merging the contents of a flat file with a SQL Server database table. I wrote a post a while ago on how call the same stored procedure multiple times without a loop shape with the ‘old’ [...]
Pingback by Using the BizTalk WCF-SQL Adapter to load a flat file into a SQL Server 2008 table « Connected Thoughts – Thiago Almeida — June 29, 2009 @ 4:20 pm
this is excellent. may i have detail description of this problem? i will be very helpfull for me.
Comment by nazmul — July 16, 2009 @ 10:59 pm
I have a similar scenario :
2 Schemas — SCHEMA-A and SCHEMA-B —> generated by SQL Adapter
I have a Orchestration variable “ID”
SCHEMA-A(Response)+ Variable needs to be Mapped to SCHEMA-B(Request)
ROOT(SCHEMA-A-Response)(Multiple) >>>>>>>>>> ROOT (SCHEMA-B-REQUEST)(Multiple Insert)
LNAME LNAME
FNAME FAME
ID (Variable inside Orchestration)
How do i achieve this suggestions please.
Thanks in advance..
Comment by Reddy — July 19, 2009 @ 8:20 am
You can try this approach for your second ‘multiple insert’ schema:
http://connectedthoughts.wordpress.com/2008/05/31/updating-repeating-nodes-in-an-xml-document-with-the-same-value-using-xpathmutatorstream/
Comment by Thiago Almeida — August 4, 2009 @ 8:23 am
This is an Excellent post
Comment by RaviKumar Bhuvanagir — November 3, 2009 @ 7:59 pm