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:
@Code nchar(5) ,@Name nchar(30), @Type nchar(10), @PartnerID int
SET NOCOUNT ON;
IF EXISTS(Select Code from tbMyTestTable tb where Code= @Code)
SET [Code] = @Code, [Name] = @Name, [Type] = @Type, [PartnerID] = @PartnerID
WHERE [Code] = @Code
INSERT INTO [MyTestDB].[dbo].[tbMyTestTable]
([Code], [Name], [Type], [PartnerID])
VALUES (@Code, @Name, @Type, @PartnerID)
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:
It gets mapped to the following XML which is then sent to the SQL Adapter:
<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>
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.