Friday, 18 September 2009

Hi all

I am REALLY excited to announce, that I will be co-authoring a book on BizTalk. I will be a part of a terrific team consisting of

  • Anush Kumar
  • Brian Loesgen
  • Charles Young
  • Jon Flanders
  • Scot Colestock
  • Tom Canter
  • Me :-)

Together we will be writing “BizTalk Server 2009 Unleashed”, which is so new, that you cannot find it on the web page of the publisher or any other sites. It is so new, that we haven’t even signed our contracts with the publisher yet, which may cause someone to quit the project if they are not happy about the contract… so nothing promised yet.

But, needless to say, I am really excited, and giving the team, also feeling quite humble :-).

This will be my first book.

Wohooo

--
eliasen

Friday, 18 September 2009 22:06:38 (Romance Daylight Time, UTC+02:00)  #    Comments [11]  | 

Hi all

So, sorry to see it, but it appears it has been almost two months since my last blog post – hope to get back on track soon.

Since the last time, I have installed Windows 7 RTM on my laptop, and one of the reasons I haven’t blogged is, that I couldn’t get Windows Live Writer Backup to restore my backup of Windows Live Writer from my old Windows XP installation. That turned out to be a silly thing… For others; You cannot restore using WLW Backup without having run Windows Live Writer first. It isn’t enough to install it, it must have been run also. Oh well.

 

I hope to entertain you all some more from now on…

 

--
eliasen

Friday, 18 September 2009 21:55:49 (Romance Daylight Time, UTC+02:00)  #    Comments [0]  | 

Hi all

Some weeks ago, I had a customer that had an Order XML and needed to fetch all the names of the ordered items based on the item number that was in the XML.

He contacted me because the solution he had thought of didn’t work. What he did was that he mapped the Order XML to a SQL Adapter schema that called an SP in SQL Server to get the item name based on the item number. The issue he ran into was, that the SP got called multiple times – once for each item, and the SQL adapter didn’t seem to batch all the results into one result for his orchestration.

So, given this simplified Order:

<ns0:Order xmlns:ns0="http://MultipleCallsToSP.Order">
  <Header>
    <CustomerName>CustomerName_0</CustomerName>
    <OrderNumber>OrderNumber_0</OrderNumber>
  </Header>
  <OrderLines>
    <OrderLine>
      <ItemNumber>21</ItemNumber>
      <Quantity>42</Quantity>
    </OrderLine>
    <OrderLine>
      <ItemNumber>42</ItemNumber>
      <Quantity>21</Quantity>
    </OrderLine>
  </OrderLines>
</ns0:Order>

He mapped it to this XML:

<ns0:GetItemNameRequest xmlns:ns0="http://eliasen.dk">
  <ns0:GetItemName ItemID="21" />
  <ns0:GetItemName ItemID="42" /> 
</ns0:GetItemNameRequest>

This was then sent to SQL Server using the SQL Adapter to call a SP named “GetItemName” which just takes an ItemID (int) as parameter and returns the ItemName hat matches the ItemID.

Now, the schema that is generated for the SQL Server request actually doesn’t allow for multiple GetItemName elements to be created, but that is changeable :-) If you set it to have maxOcurs = unbounded, then it can occur multiple times, and what happens is that the SP is called multiple times. Unfortunately, only one of the ItemNames is returned – the rest is ignored.

So the customer came to me because naturally, he needed all the ItemNames and not just one of them. I have suggested 5 possible solutions, which I will describe here.

First option
Use the pattern described at http://blog.eliasen.dk/2006/11/05/LoopingAroundElementsOfAMessage.aspx to loop around the order lines and build the resulting XML one order line at a time.

Second option
Use enveloping in the receive location in order to get one orchestration started for each order line.

Third option
Use the Database Lookup functoid to retrieve the ItemName based on the ItemID

Fourth option
Generate a comma separated list of ItemID’s in the map, and let the stored procedure use that list to return the relevant ItemNames. This has some consequences for the stored procedure. Before it looked like this:

SELECT ItemNumber, ItemName
FROM Items
WHERE Items.ItemNumber = @ItemID
FOR XML AUTO, ELEMENTS

Now, it looks like this:

SELECT ItemNumber, ItemName
FROM Items
WHERE EXISTS (select * from dbo.Split(‘,’,@items) where [Items].ItemNumber = ID)
FOR XML AUTO, ELEMENTS

@items is the parameter for the SP, which is just an nvarchar that is to contain the comma separated list.

For this to work you need the Split function, which looks like this:

CREATE FUNCTION [dbo].[Split] (@sep char(1), @s varchar(512))
RETURNS table
AS
RETURN
(    
                WITH Pieces(pn, start, stop) AS (
                      SELECT 1, 1, CHARINDEX(@sep, @s)
                      UNION ALL      
                      SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1)      
                      FROM Pieces      
                      WHERE stop > 0    
                 )
                 SELECT pn, CONVERT(int, SUBSTRING(@s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END)) AS ID
FROM Pieces
)

In order to generate the comma separated list in your map, I have written two blog posts about this issue, which you can find at http://blog.eliasen.dk/2009/06/22/HandlingCommaSeparatedValuesInsideAMapPartI.aspx and http://blog.eliasen.dk/2009/06/27/HandlingCommaSeparatedValuesInsideAMapPartII.aspx

Fifth option
The fifth and last option i want to mention is, that with the new SQL Server LOB adapter from Adapter Pack 2.0, it appears that you can do it like the customer wanted to do it in the first place with sending one XML to SQL Server and getting an accumulated response back from SQL Server based on several calls to a stored procedure. I haven’t had time to test this, but look out for another blog post about this :-)

 

Hope this helps someone.

 

--
eliasen

Friday, 18 September 2009 21:47:51 (Romance Daylight Time, UTC+02:00)  #    Comments [0]  | 

Theme design by Jelle Druyts