<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://consultingblogs.emc.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>SSIS Junkie</title><link>http://consultingblogs.emc.com/jamiethomson/default.aspx</link><description /><dc:language>en</dc:language><generator>CommunityServer 2.1 SP3 (Build: 20423.1)</generator><item><title>The curtain falls</title><link>http://consultingblogs.emc.com/jamiethomson/archive/2009/08/29/the-curtain-falls.aspx</link><pubDate>Sat, 29 Aug 2009 22:27:00 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:16154</guid><dc:creator>jamie.thomson</dc:creator><slash:comments>1</slash:comments><comments>http://consultingblogs.emc.com/jamiethomson/comments/16154.aspx</comments><wfw:commentRss>http://consultingblogs.emc.com/jamiethomson/commentrss.aspx?PostID=16154</wfw:commentRss><wfw:comment>http://consultingblogs.emc.com/jamiethomson/rsscomments.aspx?PostID=16154</wfw:comment><description>&lt;P&gt;In October 2004 I was in Orlando airport returning home from the annual SQL PASS summit and I happened to pick up a copy of MIT’s Technology Review magazine in which the cover story was an interview with Tim Berners-Lee called “Internet 2.0”.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.technologyreview.com/magazine/21/"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;MARGIN-LEFT:0px;BORDER-LEFT-WIDTH:0px;MARGIN-RIGHT:0px;" title="MIT Technology Review October 2004 cover" border=0 alt="MIT Technology Review October 2004 cover" align=left src="http://blogs.conchango.com/blogs/jamiethomson/image_7D718C76.png" width=175 height=215&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;One subject covered in the interview was the emerging phenomenon of blogging and it was then that I decided I wanted to get my own blog to talk about the stuff I was interested which, at the time, was the early beta of SQL Server Yukon (later renamed to SQL Server 2005).&lt;/P&gt;
&lt;P&gt;Soon after returning to the UK it was announced internally that Conchango were soon to support their own blog site at &lt;A href="http://blogs.conchango.com/"&gt;http://blogs.conchango.com&lt;/A&gt; and would anyone be interested in contributing. Inspired by the Berners-Lee article I threw my hat in and on 3rd November 2004 I wrote my first blog entry &lt;A href="http://blogs.conchango.com/jamiethomson/archive/2004/11/03/Intro.aspx"&gt;Intro&lt;/A&gt; where I said:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;So...I've got a blog. Now the inevitable question...what on earth to put in it?&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Well I guess I found something to write about because since that original post I’ve written another 674 of the things!:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.conchango.com/Bloggers.aspx?GroupID=6"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" title="Conchango blogger statistics" border=0 alt="Conchango blogger statistics" src="http://blogs.conchango.com/blogs/jamiethomson/image_13E42AFE.png" width=690 height=100&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Why am I telling you this? Well, this blog post is going to be both the 676th and the last at &lt;A href="http://blogs.conchango.com/jamiethomson"&gt;http://blogs.conchango.com/jamiethomson&lt;/A&gt; for in a few weeks I shall be leaving &lt;STRIKE&gt;Conchango&lt;/STRIKE&gt; EMC Consulting after five and a half very very happy years. Its been a painstaking decision to do this for I’ll be leaving behind a bunch of brilliantly talented colleagues and fun people whom it has been a genuine pleasure to be around but I feel the time is right to branch out on my own.&lt;/P&gt;
&lt;P&gt;Thanks for reading here for at least some of the past five years, see you on the other side!&lt;/P&gt;
&lt;P&gt;&lt;A href="http://twitter.com/jamiet"&gt;@Jamiet&lt;/A&gt;&lt;/P&gt;
&lt;HR&gt;

&lt;P&gt;Given my interest in all things BI I thought I’d provide some stats to summarise my activity here over the past 5 years (also because I’m not going to have access to some of this data for much later):&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;# of posts: 676 &lt;/LI&gt;
&lt;LI&gt;# of comments: 4109 &lt;/LI&gt;
&lt;LI&gt;# of hits: 6.99million &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Distribution of blog posts per month (unsurprisingly my output declined once I’d run out of stuff to talk about in regard to SSIS 2005)&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.conchango.com/blogs/jamiethomson/image_2F1C83FF.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" title="blog posts per month on http://blogs.conchango.com/jamiethomson" border=0 alt="blog posts per month on http://blogs.conchango.com/jamiethomson" src="http://blogs.conchango.com/blogs/jamiethomson/image_thumb_4DF2F7DD.png" width=883 height=383&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Number of people subscribed to my blog on Google Reader since March 2008&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.conchango.com/blogs/jamiethomson/image_180E02C3.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" title="google reader subscribers to http://blogs.conchango.com/jamiethomson" border=0 alt="google reader subscribers to http://blogs.conchango.com/jamiethomson" src="http://blogs.conchango.com/blogs/jamiethomson/image_thumb_6C5D38C6.png" width=514 height=295&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Top posts in terms of hits&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://blogs.conchango.com/jamiethomson/archive/2006/01/05/SSIS_3A00_-Suggested-Best-Practices-and-naming-conventions.aspx"&gt;Suggested Best Practices and naming conventions&lt;/A&gt; (102448 hits) &lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.conchango.com/jamiethomson/archive/2006/09/12/SSIS_3A00_-Checking-if-a-row-exists-and-if-it-does_2C00_-has-it-changed.aspx"&gt;Checking if a row exists and if it does, has it changed?&lt;/A&gt; (67851 hits) &lt;/LI&gt;&lt;/UL&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=16154" width="1" height="1"&gt;</description></item><item><title>Reporting Services FixedColumnHeaders property bug [Note to self]</title><link>http://consultingblogs.emc.com/jamiethomson/archive/2009/08/24/reporting-services-fixedcolumnheaders-property-bug-note-to-self.aspx</link><pubDate>Mon, 24 Aug 2009 08:31:00 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:16102</guid><dc:creator>jamie.thomson</dc:creator><slash:comments>0</slash:comments><comments>http://consultingblogs.emc.com/jamiethomson/comments/16102.aspx</comments><wfw:commentRss>http://consultingblogs.emc.com/jamiethomson/commentrss.aspx?PostID=16102</wfw:commentRss><wfw:comment>http://consultingblogs.emc.com/jamiethomson/rsscomments.aspx?PostID=16102</wfw:comment><description>&lt;P&gt;[Every time I come across this problem&amp;nbsp;I seem to spend a good five minutes scanning the interwebs trying to find the answer - maybe if I write it here it'll be easier to find in the future!]&lt;/P&gt;
&lt;P&gt;SQL Server Reporting Services 2008 has a bug concerning the FixedColumnHeaders property of a tablix.&lt;/P&gt;
&lt;P&gt;The property's description is given as :&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;"Indicates whether the column headers remain displayed on the page when the user scrolls the tablix data region off the page."&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Well that's not actually true because setting that property to, well,&amp;nbsp;&lt;EM&gt;anything &lt;/EM&gt;has no discernible effect. Microsoft have acknowledge the bug (without actually calling it a bug) and provided a workaround in a knowledge base article:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A class="" href="http://support.microsoft.com/kb/955822" target=_blank&gt;You cannot keep the column headers or the row headers visible when you scroll through a report in SQL Server 2008 Reporting Services&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;I haven't yet checked whether this is fixed in the recent CTP2 release build of SQL Server 2008 R2. If I find out I'll try and remember to come back and update this post.&lt;/P&gt;
&lt;P&gt;&lt;A class="" href="http://twitter.com/jamiet"&gt;@Jamiet&lt;/A&gt;&lt;/P&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=16102" width="1" height="1"&gt;</description><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/sqL+server+2008/default.aspx">sqL server 2008</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/reporting+services/default.aspx">reporting services</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/sqL+server+reporting+services/default.aspx">sqL server reporting services</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/ssrs/default.aspx">ssrs</category></item><item><title>Editing Configuration files : SSIS Nugget</title><link>http://consultingblogs.emc.com/jamiethomson/archive/2009/08/04/editing-configuration-files-ssis-nugget.aspx</link><pubDate>Tue, 04 Aug 2009 15:51:41 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:15990</guid><dc:creator>jamie.thomson</dc:creator><slash:comments>0</slash:comments><comments>http://consultingblogs.emc.com/jamiethomson/comments/15990.aspx</comments><wfw:commentRss>http://consultingblogs.emc.com/jamiethomson/commentrss.aspx?PostID=15990</wfw:commentRss><wfw:comment>http://consultingblogs.emc.com/jamiethomson/rsscomments.aspx?PostID=15990</wfw:comment><description>&lt;p&gt;Its been a long-g-g-g-g time since I did a SSIS-related post so here’s a little ditty that I picked up while reviewing some internal stuff today.&lt;/p&gt;  &lt;p&gt;Editing SSIS configuration (i.e. .dtsConfig) files isn’t particularly easy. Most people I see who try to do this use a traditional text editor like Notepad but that isn’t a great experience because the contents don’t look particularly friendly when you open them up. Observe:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.conchango.com/blogs/jamiethomson/image_2B1D2348.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://blogs.conchango.com/blogs/jamiethomson/image_thumb_1AE13582.png" width="871" height="160" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Instead you may wish to use Visual Studio which, if you’re messing about with SSIS configuration files, you should already have installed. The steps are pretty simple, firstly hit CTRL-O to open your config file. It may look something like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.conchango.com/blogs/jamiethomson/image_669CE66E.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://blogs.conchango.com/blogs/jamiethomson/image_thumb_72522DA0.png" width="834" height="93" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Well, that’s not much better but with a little wave of Visual Studio’s magic wand (otherwise known as CTRL-K, CTRL-D) then it will get turned into this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.conchango.com/blogs/jamiethomson/image_378A84CA.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://blogs.conchango.com/blogs/jamiethomson/image_thumb_1DF2D1D0.png" width="878" height="229" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;which, I’m sure you’ll agree, is a whole lot friendlier. You can save that and it will continue to work just fine, SSIS will of course ignore the whitespace (why BIDS doesn’t create configuration files like this in the first place I do not know).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://twitter.com/jamiet"&gt;@Jamiet&lt;/a&gt;&lt;/p&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=15990" width="1" height="1"&gt;</description><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/SQL+Server+Integration+Services/default.aspx">SQL Server Integration Services</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/SSIS/default.aspx">SSIS</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/configurations/default.aspx">configurations</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/Nugget/default.aspx">Nugget</category></item><item><title>Peering into the SQL Azure documentation</title><link>http://consultingblogs.emc.com/jamiethomson/archive/2009/08/04/peering-into-the-sql-azure-documentation.aspx</link><pubDate>Tue, 04 Aug 2009 09:54:25 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:15982</guid><dc:creator>jamie.thomson</dc:creator><slash:comments>3</slash:comments><comments>http://consultingblogs.emc.com/jamiethomson/comments/15982.aspx</comments><wfw:commentRss>http://consultingblogs.emc.com/jamiethomson/commentrss.aspx?PostID=15982</wfw:commentRss><wfw:comment>http://consultingblogs.emc.com/jamiethomson/rsscomments.aspx?PostID=15982</wfw:comment><description>&lt;p&gt;Some documentation for SQL Azure has been released on MSDN at &lt;a title="http://msdn.microsoft.com/en-us/library/ee336279.aspx" href="http://msdn.microsoft.com/en-us/library/ee336279.aspx"&gt;http://msdn.microsoft.com/en-us/library/ee336279.aspx&lt;/a&gt; and upon reading there are some interesting nuggets of information that are worth calling out.&lt;/p&gt;  &lt;p&gt;Under a section headed “Key benefits of the service” the following statement appears:&lt;/p&gt;  &lt;blockquote&gt;   &lt;h5&gt;&lt;em&gt;Scalability&lt;/em&gt;&lt;/h5&gt;    &lt;p&gt;&lt;em&gt;A key advantage of SQL Azure is the ease with which you can scale your solution. After partitioning your data, the service scales as your data grows.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Hmmm…there’s two seemingly contradictory statements in there, “ease” and “partitioning your data”. Last time I looked there was nothing particularly easy about partitioning data, certainly not when it is going to be partitioned across multiple databases. I wonder if the captain of the Titanic proudly declared “Sailing to New York will be easy once we’re past all those meddlesome icebergs”!&lt;/p&gt;  &lt;p&gt;Another name for this partitioning technique is sharding for which Dare Obasanjo has a great discussion up at &lt;a href="http://www.25hoursaday.com/weblog/2009/01/16/BuildingScalableDatabasesProsAndConsOfVariousDatabaseShardingSchemes.aspx"&gt;Building Scalable Databases: Pros and Cons of Various Database Sharding Schemes&lt;/a&gt;. Dare says database sharding is:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;the process of splitting up a database across multiple machines to improve the scalability of an application&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;which is exactly what SQL Azure proposes except that they use the word “partitioning” rather than “splitting” and its across multiple virtual instances rather than multiple machines.&lt;/p&gt;  &lt;p&gt;Dare talks about numerous disadvantages of sharding but the key one is that you lose the benefit of referential integrity (RI) which is, to my mind, THE main reason for using a relational database in the first place. Let’s take a look at a simple example. Suppose (incredibly hypothetically) that Amazon adopted SQL Azure and chose to shard its product catalogue across multiple instances; they then face the very real situation where it is not possible to have full RI between their products, customers and the orders that link them together. An order would most likely contain products from different shards therefore which shard should the order live on? Maybe Amazon could shard the order line items according by product but how do they enforce RI back to the order header and, onward, to the customer? Clearly Amazon can’t enforce RI across shards so they have to use some different data storage mechanism in which case why bother using SQL Azure at all?&lt;/p&gt;  &lt;p&gt;This is an extreme case but its one that you have to consider when using SQL Azure and the problem is exacerbated when you consider that the maximum size of a database in SQL Azure is 10GB. “Oh, you want to store your new product in my database? You say it’ll only use up 5KB of storage? No can do, you’re maxed out! Sorry!” (Although arguably the 10GB limit is an advantage because at least your shard’s maximum limit is absolute rather than theoretical.)&lt;/p&gt;  &lt;p&gt;There are of course solutions to these problems and they generally involve writing your application to workaround these limitations. Doing that is, however, an expensive and time-consuming undertaking which is something anyone adopting SQL Azure needs to be aware of and you won’t find it written down anywhere in the SQL Azure documentation.&lt;/p&gt;  &lt;p&gt;Be aware, that’s all I’m saying! If your database is not going to grow anywhere near 10GB then SQL Azure might well be a good fit for you.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://twitter.com/jamiet"&gt;@Jamiet&lt;/a&gt;&lt;/p&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=15982" width="1" height="1"&gt;</description><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/azure/default.aspx">azure</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/sharding/default.aspx">sharding</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/SQL+Azure/default.aspx">SQL Azure</category></item><item><title>.Net Service bus demo by EasyJet at UK Azure Net user group meeting</title><link>http://consultingblogs.emc.com/jamiethomson/archive/2009/07/30/net-service-bus-demo-by-easyjet-at-uk-azure-net-user-group-meeting.aspx</link><pubDate>Thu, 30 Jul 2009 14:38:00 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:15957</guid><dc:creator>jamie.thomson</dc:creator><slash:comments>0</slash:comments><comments>http://consultingblogs.emc.com/jamiethomson/comments/15957.aspx</comments><wfw:commentRss>http://consultingblogs.emc.com/jamiethomson/commentrss.aspx?PostID=15957</wfw:commentRss><wfw:comment>http://consultingblogs.emc.com/jamiethomson/rsscomments.aspx?PostID=15957</wfw:comment><description>&lt;p&gt;Yesterday evening I attended the second meeting of the UK Azure Net user group in London Victoria. Normally this wouldn’t in itself be blog worthy but one of the presentations given really piqued my interest and I wanted to draw some attention to it.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://cid-61ea3f98c8957a87.profile.live.com/"&gt;Bert Craven&lt;/a&gt; from &lt;a href="http://easyjet.com/"&gt;EasyJet&lt;/a&gt; gave a demo of an application that EasyJet are going to be trialling in the near future, one that allows their employees to use handheld devices to check-in passengers rather than have those passengers queue up at check-in desks. The really compelling part of the demo though was the underlying technology; Bert’s team are using the Azure .Net Service Bus to expose service endpoints from their &lt;em&gt;existing &lt;/em&gt;firewalled systems in order to make them consumable from the handheld devices. It was (as I fed back to Bert last night) by some distance the best Azure demo I’ve seen yet&lt;/p&gt;  &lt;p&gt;Bert claimed that they had to do little more than change a configuration file in order to expose their services in this way and that’s when I had the “AHA” moment that had thus far escaped me and I began to understand why people like &lt;a href="http://blogs.conchango.com/simonevans/"&gt;Simon Evans&lt;/a&gt; and &lt;a href="http://blogs.msdn.com/simondavies/default.aspx"&gt;Simon Davies&lt;/a&gt; have been speaking so enthusiastically about the .Net Service Bus. I realised the power inherent in this thing - it allows you to deliver features that previously would have taken reams and reams of code using little more than a configuration change.&lt;/p&gt;  &lt;p&gt;Bert’s presentation included a demo where a service and a client were able to communicate via a service bus relay in under a second – this involved two round trips to a datacentre on the west coast of the US no less. He also showed data being synchronised between two handheld devices (running on emulators) via the service bus and again in sub-second intervals. To say this was impressive is an understatement.&lt;/p&gt;  &lt;p&gt;Bert has blogged about his talk at &lt;a href="http://bertcraven.spaces.live.com/blog/cns!61EA3F98C8957A87!480.entry"&gt;Azure Service Bus Presentation and Demo Code&lt;/a&gt; and as the title suggests he has made demo code available there. I’m going away now to try it for myself.&lt;/p&gt;  &lt;p&gt;That’s all really. The .Net Service Bus is the ace in the pack of Microsoft’s Azure offering and if you work in B2B scenarios or with distributed systems it could be well worth spending some time understanding it.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://twitter.com/jamiet"&gt;@Jamiet&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;UPDATE: A video of Bert’s session is now available:&lt;/p&gt;  &lt;div id="xrPlayerEmbededDiv68f8580ab54342349617c9c83a0e1353"&gt;&lt;object id="xrPlayerEmbeded68f8580ab54342349617c9c83a0e1353" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,124,0" width="640" height="360"&gt;&lt;param name="movie" value="http://exposureroom.com/flash/XRVideoPlayer2.swf?domain=exposureroom.com/&amp;amp;assetId=68f8580ab54342349617c9c83a0e1353&amp;amp;size=md&amp;amp;titleColor=#ffffff" /&gt;&lt;param name="allowNetworking" value="all" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;param name="allowScriptAccess" value="always" /&gt;&lt;param name="allowFullScreen" value="True" /&gt;&lt;embed name="xrPlayerEmbeded68f8580ab54342349617c9c83a0e1353" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://exposureroom.com/flash/XRVideoPlayer2.swf?domain=exposureroom.com/&amp;amp;assetId=68f8580ab54342349617c9c83a0e1353&amp;amp;size=md&amp;amp;titleColor=#ffffff" quality="best" width="640" height="360" allowScriptAccess="always" allowFullScreen="True"&gt;&lt;/embed&gt;&lt;/object&gt;    &lt;div&gt;&lt;a title="UK Azure User Group Meeting#2 Talk #2: EasyJet and Azure (Bert Craven) by UK AzureUserGroup:View it on ExposureRoom" href="http://exposureroom.com/68f8580ab54342349617c9c83a0e1353"&gt;View on ExposureRoom&lt;/a&gt;&lt;/div&gt; &lt;/div&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=15957" width="1" height="1"&gt;</description><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/azure/default.aspx">azure</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/Service+Bus/default.aspx">Service Bus</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/Easyjet/default.aspx">Easyjet</category></item><item><title>Sync is the word</title><link>http://consultingblogs.emc.com/jamiethomson/archive/2009/07/22/sync-is-the-word.aspx</link><pubDate>Wed, 22 Jul 2009 16:56:22 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:15900</guid><dc:creator>jamie.thomson</dc:creator><slash:comments>0</slash:comments><comments>http://consultingblogs.emc.com/jamiethomson/comments/15900.aspx</comments><wfw:commentRss>http://consultingblogs.emc.com/jamiethomson/commentrss.aspx?PostID=15900</wfw:commentRss><wfw:comment>http://consultingblogs.emc.com/jamiethomson/rsscomments.aspx?PostID=15900</wfw:comment><description>&lt;p&gt;I &lt;a href="http://twitter.com/jamiet/status/2780989286"&gt;recently tweeted&lt;/a&gt; the following rather silly little ditty…&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Sync is the word       &lt;br /&gt;Its in Groove, its in GMail        &lt;br /&gt;Sync works any time, any place, in motion        &lt;br /&gt;Sync is the way we'll be storing&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Ahem, yes. Well… silly but with a relevant point. Sync is becoming an integral aspect of how we build and consume apps and I expect that trend to increase in the years to come. Let’s look at the evidence. Big tech companies are tripping up over themselves with their efforts to build synchronisation capabilities into their products:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Google&lt;/strong&gt; use &lt;a href="http://gears.google.com/"&gt;Google Gears&lt;/a&gt; to enable you to &lt;a href="http://gmailblog.blogspot.com/2009/01/new-in-labs-offline-gmail.html"&gt;read your GMail offline&lt;/a&gt; as well as &lt;a href="http://www.google.com/help/reader/offline.html"&gt;your Google Reader subscriptions&lt;/a&gt;. They also have &lt;a href="http://www.google.com/apps/intl/en/business/outlook_sync.html#utm_medium=et&amp;amp;utm_source=us-en-ogb&amp;amp;utm_campaign=en"&gt;Google Apps Sync for Microsoft Outlook&lt;/a&gt; which enables you to synchronise Microsoft Outlook with GMail, Google Calendar and Google Contacts.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Apple&lt;/strong&gt; pioneered syncing capabilities with &lt;a href="http://www.apple.com/itunes/download/"&gt;iTunes&lt;/a&gt; and iPod and are now pushing further into the sync space with &lt;a href="http://www.me.com/"&gt;MobileMe&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Twitter &lt;/strong&gt;has a plethora of apps available for syncing your Twitter feed to an offline store including &lt;a href="http://tweetdeck.com/"&gt;Tweetdeck&lt;/a&gt; and &lt;a href="http://www.thirteen23.com/experiences/desktop/blu/"&gt;Blu&lt;/a&gt; to name but two&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Microsoft&lt;/strong&gt; have been in the sync game for a fair while, most prominently through the ability to synchronise email between Exchange &amp;amp; Outlook and between Exchange &amp;amp; mobile phone (via &lt;a href="http://msdn.microsoft.com/en-us/library/ms879772.aspx"&gt;ActiveSync&lt;/a&gt;) – capabilities that are now available to consumers via &lt;a href="http://mail.live.com/"&gt;Hotmail&lt;/a&gt; and &lt;a href="http://download.live.com/wlmail"&gt;Windows Live Mail&lt;/a&gt;. They are also investing heavily in synchronisation platforms such as the &lt;a href="http://code.msdn.microsoft.com/sync"&gt;Sync Framework&lt;/a&gt; and &lt;a href="http://www.mesh.com"&gt;Live Mesh&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I often hear that we are living in an increasingly connected world but in some ways the opposite is true, we are actually living in an increasingly &lt;em&gt;dis&lt;/em&gt;connected world due to the increasing number of devices in our pocket that are online either some or none of the time. Until online connectivity is ubiquitous sync is an essential part of any smartphone platform.&lt;/p&gt;  &lt;p&gt;Indeed, almost five years ago &lt;a href="http://www.russellbeattie.com/blog/about"&gt;Russell Beattie&lt;/a&gt; said:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;“Syncing is *THE* most important piece of technology in the future of mobility. Voice is and will be the number one service, but after that it's syncing. Syncing! SYNCING!”&lt;/em&gt;      &lt;br /&gt;&lt;em&gt;from &lt;/em&gt;&lt;a href="http://www.russellbeattie.com/notebook/1008086.html"&gt;&lt;em&gt;Syncing. Syncing! Syncing! Syncing! SYNCING!!!&lt;/em&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I quite agree! More about sync to follow…&lt;/p&gt;  &lt;p&gt;&lt;a href="http://twitpic.com/jamiet"&gt;@Jamiet&lt;/a&gt;&lt;/p&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=15900" width="1" height="1"&gt;</description><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/sync/default.aspx">sync</category></item><item><title>String Aggregation in T-SQL &amp; PL-SQL : SQL Nugget</title><link>http://consultingblogs.emc.com/jamiethomson/archive/2009/07/16/string-aggregation-in-t-sql-amp-pl-sql.aspx</link><pubDate>Thu, 16 Jul 2009 12:32:00 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:15863</guid><dc:creator>jamie.thomson</dc:creator><slash:comments>6</slash:comments><comments>http://consultingblogs.emc.com/jamiethomson/comments/15863.aspx</comments><wfw:commentRss>http://consultingblogs.emc.com/jamiethomson/commentrss.aspx?PostID=15863</wfw:commentRss><wfw:comment>http://consultingblogs.emc.com/jamiethomson/rsscomments.aspx?PostID=15863</wfw:comment><description>&lt;P&gt;In my current day job I’m doing a lot of work against an Oracle back-end and I’ve just come across a situation where I need to do some string aggregation. Effectively I needed to turn this:&lt;/P&gt;
&lt;TABLE border=1 cellSpacing=0 cellPadding=2 width=400&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;H5&gt;Parent&lt;/H5&gt;&lt;/TD&gt;
&lt;TD&gt;
&lt;H5&gt;Child&lt;/H5&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Charles&lt;/TD&gt;
&lt;TD&gt;William&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Charles&lt;/TD&gt;
&lt;TD&gt;Harry&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Anne&lt;/TD&gt;
&lt;TD&gt;Peter&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Anne&lt;/TD&gt;
&lt;TD&gt;Zara&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Andrew&lt;/TD&gt;
&lt;TD&gt;Beatrice&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Andrew&lt;/TD&gt;
&lt;TD&gt;Eugenie&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;into this:&lt;/P&gt;
&lt;TABLE border=1 cellSpacing=0 cellPadding=2 width=400&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;H5&gt;Parent&lt;/H5&gt;&lt;/TD&gt;
&lt;TD&gt;
&lt;H5&gt;Children&lt;/H5&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Charles&lt;/TD&gt;
&lt;TD&gt;William,Harry&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Anne&lt;/TD&gt;
&lt;TD&gt;Peter,Zara&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Andrew&lt;/TD&gt;
&lt;TD&gt;Eugenie,Beatrice&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;In other words I wanted to take a list of children per parent and produce a comma-delimited list of each of their children.&lt;/P&gt;
&lt;P&gt;I know how to do this in T-SQL, you use the FOR XML PATH(‘’) construct like so:&lt;/P&gt;
&lt;DIV id=codeSnippetWrapper&gt;
&lt;DIV style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:#f4f4f4;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;" id=codeSnippet&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:white;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4&gt;&lt;FONT face="Lucida Console"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;with&lt;/SPAN&gt; t  &lt;SPAN style="COLOR:#0000ff;"&gt;as&lt;/SPAN&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:#f4f4f4;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4&gt;&lt;FONT face="Lucida Console"&gt; &lt;SPAN style="COLOR:#0000ff;"&gt;select&lt;/SPAN&gt; &lt;SPAN style="COLOR:#ff0000;"&gt;'Charles'&lt;/SPAN&gt; parent, &lt;SPAN style="COLOR:#ff0000;"&gt;'William'&lt;/SPAN&gt; child &lt;SPAN style="COLOR:#0000ff;"&gt;union&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:white;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4&gt;&lt;FONT face="Lucida Console"&gt; &lt;SPAN style="COLOR:#0000ff;"&gt;select&lt;/SPAN&gt; &lt;SPAN style="COLOR:#ff0000;"&gt;'Charles'&lt;/SPAN&gt;, &lt;SPAN style="COLOR:#ff0000;"&gt;'Harry'&lt;/SPAN&gt; &lt;SPAN style="COLOR:#0000ff;"&gt;union&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:#f4f4f4;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4&gt;&lt;FONT face="Lucida Console"&gt; &lt;SPAN style="COLOR:#0000ff;"&gt;select&lt;/SPAN&gt; &lt;SPAN style="COLOR:#ff0000;"&gt;'Anne'&lt;/SPAN&gt;, &lt;SPAN style="COLOR:#ff0000;"&gt;'Peter'&lt;/SPAN&gt; &lt;SPAN style="COLOR:#0000ff;"&gt;union&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:white;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4&gt;&lt;FONT face="Lucida Console"&gt; &lt;SPAN style="COLOR:#0000ff;"&gt;select&lt;/SPAN&gt; &lt;SPAN style="COLOR:#ff0000;"&gt;'Anne'&lt;/SPAN&gt;, &lt;SPAN style="COLOR:#ff0000;"&gt;'Zara'&lt;/SPAN&gt; &lt;SPAN style="COLOR:#0000ff;"&gt;union&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:#f4f4f4;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4&gt;&lt;FONT face="Lucida Console"&gt; &lt;SPAN style="COLOR:#0000ff;"&gt;select&lt;/SPAN&gt; &lt;SPAN style="COLOR:#ff0000;"&gt;'Andrew'&lt;/SPAN&gt;, &lt;SPAN style="COLOR:#ff0000;"&gt;'Beatrice'&lt;/SPAN&gt; &lt;SPAN style="COLOR:#0000ff;"&gt;union&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:white;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4 face="Lucida Console"&gt; &lt;SPAN style="COLOR:#0000ff;"&gt;select&lt;/SPAN&gt; &lt;SPAN style="COLOR:#ff0000;"&gt;'Andrew'&lt;/SPAN&gt;, &lt;SPAN style="COLOR:#ff0000;"&gt;'Eugenie'&lt;/SPAN&gt; &lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:#f4f4f4;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4 face="Lucida Console"&gt;)&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:white;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4&gt;&lt;FONT face="Lucida Console"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;SELECT&lt;/SPAN&gt; parent, STUFF( ( &lt;SPAN style="COLOR:#0000ff;"&gt;SELECT&lt;/SPAN&gt; &lt;SPAN style="COLOR:#ff0000;"&gt;','&lt;/SPAN&gt;+ child &lt;/FONT&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:#f4f4f4;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4 face="Lucida Console"&gt;                        &lt;SPAN style="COLOR:#0000ff;"&gt;FROM&lt;/SPAN&gt; t a &lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:white;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4 face="Lucida Console"&gt;                        &lt;SPAN style="COLOR:#0000ff;"&gt;WHERE&lt;/SPAN&gt; b.parent = a.parent &lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:#f4f4f4;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4 face="Lucida Console"&gt;                        &lt;SPAN style="COLOR:#0000ff;"&gt;FOR&lt;/SPAN&gt; XML &lt;SPAN style="COLOR:#0000ff;"&gt;PATH&lt;/SPAN&gt;(&lt;SPAN style="COLOR:#ff0000;"&gt;''&lt;/SPAN&gt;)),1 ,1, &lt;SPAN style="COLOR:#ff0000;"&gt;''&lt;/SPAN&gt;)  children&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:white;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4&gt;&lt;FONT face="Lucida Console"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;FROM&lt;/SPAN&gt; t b &lt;/FONT&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:#f4f4f4;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4&gt;&lt;FONT face="Lucida Console"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;GROUP&lt;/SPAN&gt; &lt;SPAN style="COLOR:#0000ff;"&gt;BY&lt;/SPAN&gt; parent&lt;/FONT&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;which, yes, turned this:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.conchango.com/blogs/jamiethomson/image_1D376E50.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" title=image border=0 alt=image src="http://blogs.conchango.com/blogs/jamiethomson/image_thumb_6E71B5AD.png" width=187 height=165&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;into this:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.conchango.com/blogs/jamiethomson/image_46CB3983.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" title=image border=0 alt=image src="http://blogs.conchango.com/blogs/jamiethomson/image_thumb_3B357C44.png" width=244 height=141&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Unfortunately I didn’t know how to accomplish it in Oracle however after a bit of searching around I found the answer:&lt;/P&gt;
&lt;DIV id=codeSnippetWrapper&gt;
&lt;DIV style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:#f4f4f4;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;" id=codeSnippet&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:white;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4&gt;&lt;FONT face="Lucida Console"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;with&lt;/SPAN&gt; t  &lt;SPAN style="COLOR:#0000ff;"&gt;as&lt;/SPAN&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:#f4f4f4;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4&gt;&lt;FONT face="Lucida Console"&gt; &lt;SPAN style="COLOR:#0000ff;"&gt;select&lt;/SPAN&gt; &lt;SPAN style="COLOR:#ff0000;"&gt;'Charles'&lt;/SPAN&gt; parent, &lt;SPAN style="COLOR:#ff0000;"&gt;'William'&lt;/SPAN&gt; child &lt;SPAN style="COLOR:#0000ff;"&gt;from&lt;/SPAN&gt; dual &lt;SPAN style="COLOR:#0000ff;"&gt;union&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:white;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4&gt;&lt;FONT face="Lucida Console"&gt; &lt;SPAN style="COLOR:#0000ff;"&gt;select&lt;/SPAN&gt; &lt;SPAN style="COLOR:#ff0000;"&gt;'Charles'&lt;/SPAN&gt;, &lt;SPAN style="COLOR:#ff0000;"&gt;'Harry'&lt;/SPAN&gt; &lt;SPAN style="COLOR:#0000ff;"&gt;from&lt;/SPAN&gt; dual &lt;SPAN style="COLOR:#0000ff;"&gt;union&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:#f4f4f4;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4&gt;&lt;FONT face="Lucida Console"&gt; &lt;SPAN style="COLOR:#0000ff;"&gt;select&lt;/SPAN&gt; &lt;SPAN style="COLOR:#ff0000;"&gt;'Anne'&lt;/SPAN&gt;, &lt;SPAN style="COLOR:#ff0000;"&gt;'Peter'&lt;/SPAN&gt; &lt;SPAN style="COLOR:#0000ff;"&gt;from&lt;/SPAN&gt; dual &lt;SPAN style="COLOR:#0000ff;"&gt;union&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:white;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4&gt;&lt;FONT face="Lucida Console"&gt; &lt;SPAN style="COLOR:#0000ff;"&gt;select&lt;/SPAN&gt; &lt;SPAN style="COLOR:#ff0000;"&gt;'Anne'&lt;/SPAN&gt;, &lt;SPAN style="COLOR:#ff0000;"&gt;'Zara'&lt;/SPAN&gt; &lt;SPAN style="COLOR:#0000ff;"&gt;from&lt;/SPAN&gt; dual &lt;SPAN style="COLOR:#0000ff;"&gt;union&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:#f4f4f4;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4&gt;&lt;FONT face="Lucida Console"&gt; &lt;SPAN style="COLOR:#0000ff;"&gt;select&lt;/SPAN&gt; &lt;SPAN style="COLOR:#ff0000;"&gt;'Andrew'&lt;/SPAN&gt;, &lt;SPAN style="COLOR:#ff0000;"&gt;'Beatrice'&lt;/SPAN&gt; &lt;SPAN style="COLOR:#0000ff;"&gt;from&lt;/SPAN&gt; dual &lt;SPAN style="COLOR:#0000ff;"&gt;union&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:white;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4 face="Lucida Console"&gt; &lt;SPAN style="COLOR:#0000ff;"&gt;select&lt;/SPAN&gt; &lt;SPAN style="COLOR:#ff0000;"&gt;'Andrew'&lt;/SPAN&gt;, &lt;SPAN style="COLOR:#ff0000;"&gt;'Eugenie'&lt;/SPAN&gt; &lt;SPAN style="COLOR:#0000ff;"&gt;from&lt;/SPAN&gt; dual&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:#f4f4f4;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4 face="Lucida Console"&gt;)&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:white;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4&gt;&lt;FONT face="Lucida Console"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;select&lt;/SPAN&gt; parent, rtrim(xmlagg(xmlelement(e,child || &lt;SPAN style="COLOR:#ff0000;"&gt;','&lt;/SPAN&gt;))&lt;/FONT&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:#f4f4f4;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4 face="Lucida Console"&gt;                .&lt;SPAN style="COLOR:#0000ff;"&gt;extract&lt;/SPAN&gt;(&lt;SPAN style="COLOR:#ff0000;"&gt;'//text()'&lt;/SPAN&gt;),&lt;SPAN style="COLOR:#ff0000;"&gt;','&lt;/SPAN&gt;) childs &lt;SPAN style="COLOR:#0000ff;"&gt;from&lt;/SPAN&gt; t&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="BORDER-BOTTOM-STYLE:none;TEXT-ALIGN:left;PADDING-BOTTOM:0px;LINE-HEIGHT:12pt;BORDER-RIGHT-STYLE:none;BACKGROUND-COLOR:white;MARGIN:0em;PADDING-LEFT:0px;WIDTH:100%;PADDING-RIGHT:0px;FONT-FAMILY:'Courier New', courier, monospace;DIRECTION:ltr;BORDER-TOP-STYLE:none;COLOR:black;FONT-SIZE:8pt;BORDER-LEFT-STYLE:none;OVERFLOW:visible;PADDING-TOP:0px;"&gt;&lt;FONT size=4&gt;&lt;FONT face="Lucida Console"&gt;&lt;SPAN style="COLOR:#0000ff;"&gt;group&lt;/SPAN&gt; &lt;SPAN style="COLOR:#0000ff;"&gt;by&lt;/SPAN&gt; parent&lt;/FONT&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;So, now you know. And so will I if I ever need to find this again!&lt;/P&gt;
&lt;P&gt;&lt;A href="http://twitter.com/jamiet"&gt;@Jamiet&lt;/A&gt;&lt;/P&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=15863" width="1" height="1"&gt;</description><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/Oracle/default.aspx">Oracle</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/T-SQL/default.aspx">T-SQL</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/Nugget/default.aspx">Nugget</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/pl-sql/default.aspx">pl-sql</category></item><item><title>The Longest Tweet</title><link>http://consultingblogs.emc.com/jamiethomson/archive/2009/07/10/the-longest-tweet.aspx</link><pubDate>Fri, 10 Jul 2009 10:59:45 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:15811</guid><dc:creator>jamie.thomson</dc:creator><slash:comments>0</slash:comments><comments>http://consultingblogs.emc.com/jamiethomson/comments/15811.aspx</comments><wfw:commentRss>http://consultingblogs.emc.com/jamiethomson/commentrss.aspx?PostID=15811</wfw:commentRss><wfw:comment>http://consultingblogs.emc.com/jamiethomson/rsscomments.aspx?PostID=15811</wfw:comment><description>&lt;p&gt;I read an article today called &lt;a href="http://www.forbes.com/2009/07/09/longest-tweet-ever-technology-internet-forbes.html"&gt;The Longest Tweet In History&lt;/a&gt; which explained how it is now possible to send Tweets via Twitter that are longer than the supposed 140 character limit.&lt;/p&gt;  &lt;p&gt;As it happens I’ve written a noddy app called &lt;a href="http://tweetpoll.cloudapp.net/"&gt;Tweetpoll&lt;/a&gt; onto Windows Azure that periodically polls Twitter’s public timeline to determine the distribution of Tweet length and displays that distribution at &lt;a title="http://tweetpoll.cloudapp.net/" href="http://tweetpoll.cloudapp.net/"&gt;http://tweetpoll.cloudapp.net/&lt;/a&gt;. Here’s a screenshot of the latest distribution:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.conchango.com/blogs/jamiethomson/image_5216863A.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://blogs.conchango.com/blogs/jamiethomson/image_thumb_3CB8D0D2.png" width="713" height="243" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This is based on a sample set of 2940150 tweets (so far). Unsurprisingly its a fairly smooth curve (I can’t explain the peaks though – probably a bug in my code) although before I started I expected the frequency of tweet lengths to increase exponentially and clearly that’s not the case because we have a sustained increase around 30-50 characters before dropping off again.&lt;/p&gt;  &lt;p&gt;Anyway, I digress. Its been running a couple of months now and I became puzzled when, soon after launching it, I began getting results that were greater than 140 characters (as you can see on the graph above). I didn’t have an explanation for those numbers so I set about uncovering why. Three days ago I deployed an update to the app so that it now explicitly captures all tweets greater than 140 characters and stores them somewhere. Thanks to &lt;a href="http://blogs.conchango.com/jamiethomson/archive/2009/07/06/linqpad-and-azure.aspx"&gt;my new best friend&lt;/a&gt; LINQPad and the following query:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;var results = svc.LongTweetsTable.ToList().Select(r =&amp;gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; { r.RowKey, Length = r.RowKey.Length})&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;                    .OrderByDescending(r =&amp;gt; r.Length );&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;I can now find out what’s going on in those tweets:&lt;/p&gt;
&lt;a href="http://blogs.conchango.com/blogs/jamiethomson/image_2350CD98.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://blogs.conchango.com/blogs/jamiethomson/image_thumb_28BF3E3C.png" width="701" height="346" /&gt;&lt;/a&gt; 

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Notice anything about those tweets? They all contain either “&amp;amp;lt;” or “&amp;amp;gt;” which are the escape characters for less-than/greater-than symbols in markup and hence the mystery is explained; the markup for tweets might well be longer than the actual tweet itself. Pretty logical if you think about it although it didn’t occur to me without actually examining the data. That’s an important lesson learned – make sure you know your data intimately.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://twitgoo.com/jamiet"&gt;@Jamiet&lt;/a&gt;&lt;/p&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=15811" width="1" height="1"&gt;</description><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/twitter/default.aspx">twitter</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/windows+azure/default.aspx">windows azure</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/azure/default.aspx">azure</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/tweetpoll/default.aspx">tweetpoll</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/LINQPad/default.aspx">LINQPad</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/LINQ/default.aspx">LINQ</category></item><item><title>Kapow – ETL for HTML</title><link>http://consultingblogs.emc.com/jamiethomson/archive/2009/07/08/kapow-etl-for-html.aspx</link><pubDate>Wed, 08 Jul 2009 21:29:21 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:15795</guid><dc:creator>jamie.thomson</dc:creator><slash:comments>1</slash:comments><comments>http://consultingblogs.emc.com/jamiethomson/comments/15795.aspx</comments><wfw:commentRss>http://consultingblogs.emc.com/jamiethomson/commentrss.aspx?PostID=15795</wfw:commentRss><wfw:comment>http://consultingblogs.emc.com/jamiethomson/rsscomments.aspx?PostID=15795</wfw:comment><description>&lt;p&gt;A couple of weeks ago &lt;a href="http://cid-7b84b0f2c239489a.profile.live.com/"&gt;Chris Webb&lt;/a&gt; sent me an IM telling me about a new technology he’d just seen a demo of called Kapow. Chris has since blogged about it at &lt;a href="http://cwebbbi.spaces.live.com/blog/cns!7B84B0F2C239489A!4586.entry"&gt;Kapow Technologies&lt;/a&gt; and in that blog post he described Kapow as:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;“a cross between a screenscraper and an ETL tool”&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;That’s a very apt description, for what Kapow enables you to do is build what are effectively ETL packages (although they call them Robots) that extract data from HTML pages and either (a) load it into a database for you or (more interestingly) (b) make that data available as a RESTful web service. A robot pulls out the data embedded in the markup and presents it as strongly-typed data entities.&lt;/p&gt;  &lt;p&gt;I never really thought about a web page as being structured data but actually nothing could be further from the truth; HTML is after all nothing more than a hierarchical dataset with the added luxury of metadata - otherwise known as the Document Object Model (DOM). Kapow takes that structured data and its rich metadata, parses it for us, and presents it to us in ways that are easily consumable.&lt;/p&gt;  &lt;p&gt;I was given a tour of Kapow by their UK rep Dominic Dunkley. Dominic had a great demo where he built, from scratch, a Kapow robot that:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;visited a search engine before…&lt;/li&gt;    &lt;li&gt;…entering a search term (in this case “EMC”)&lt;/li&gt;    &lt;li&gt;iterated over each page of results within which it…&lt;/li&gt;    &lt;li&gt;…iterated over each search result….&lt;/li&gt;    &lt;li&gt;…and extracted the title, URL and description before…&lt;/li&gt;    &lt;li&gt;…making all the search results available in a strongly-typed dataset&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;It all took about 15 minutes and that was with him pausing to explain it step-by-step. That demo really grabbed my attention because I realised that not only does Kapow have the ability to parse the DOM but it also has notions of &lt;em&gt;workflow &lt;/em&gt;and &lt;em&gt;data composition&lt;/em&gt; which are of course two vital features of any ETL tool.&lt;/p&gt;  &lt;p&gt;I’m reminded of 3scale Networks that I mentioned in my blog post &lt;a href="http://blogs.conchango.com/jamiethomson/archive/2009/06/23/enterprise-mashups.aspx"&gt;Enterprise Mashups&lt;/a&gt; a couple of weeks back (it was actually after reading that blog post that Chris got in touch with me); in that I describe how 3scale have taken information made freely available by the United Nations at &lt;a title="http://data.un.org/" href="http://data.un.org/"&gt;http://data.un.org/&lt;/a&gt; and made it available as an easily consumable data service. In essence this same service could be built using Kapow without being monotonously handcrafted which is how I suspect 3scale did it.&lt;/p&gt;  &lt;p&gt;I’m hoping I have some reason to use Kapow in the future because I think there are some very interesting scenarios that come into play here. Chiefly, as Chris pointed out in his blog post, we can pull data from any web site and use it for BI purposes. For example, suppose you work for an airline and you want to easily compare your advertised prices with those of your competitors – Kapow is a one-stop shop for enabling that.&lt;/p&gt;  &lt;p&gt;Impressive stuff. If you’re interested go and check out Kapow for yourself at &lt;a title="http://kapowtech.com/index.php/solutions/web-and-business-intelligence" href="http://kapowtech.com/index.php/solutions/web-and-business-intelligence"&gt;http://kapowtech.com/index.php/solutions/web-and-business-intelligence&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://twitter.com/jamiet"&gt;@Jamiet&lt;/a&gt;&lt;/p&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=15795" width="1" height="1"&gt;</description><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/Kapow/default.aspx">Kapow</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/etl/default.aspx">etl</category></item><item><title>LINQPad and Azure</title><link>http://consultingblogs.emc.com/jamiethomson/archive/2009/07/06/linqpad-and-azure.aspx</link><pubDate>Mon, 06 Jul 2009 15:51:19 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:15756</guid><dc:creator>jamie.thomson</dc:creator><slash:comments>2</slash:comments><comments>http://consultingblogs.emc.com/jamiethomson/comments/15756.aspx</comments><wfw:commentRss>http://consultingblogs.emc.com/jamiethomson/commentrss.aspx?PostID=15756</wfw:commentRss><wfw:comment>http://consultingblogs.emc.com/jamiethomson/rsscomments.aspx?PostID=15756</wfw:comment><description>&lt;p&gt;Since I started dealing with Azure tables I’ve become frustrated that there is no ad-hoc query tool, nothing equivalent to SQL Server Management Studio. Then I heard about &lt;a href="http://www.linqpad.net/"&gt;LINQPad&lt;/a&gt; and figured there must be a way to use it to query Azure tables using LINQ and indeed there is as I’ll explain here (this post assumes that you have a working knowledge of LINQPad and Azure storage).&lt;/p&gt;  &lt;p&gt;Firstly you need to reference the correct assemblies. I’ve been using the StorageClient that is provided with the Azure Samples in the Azure SDK (&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=B44C10E8-425C-417F-AF10-3D2839A5A362&amp;amp;displaylang=en"&gt;March 2009 CTP of the SDK linked here&lt;/a&gt;) which in turn uses ADO.Net Services client library hence you’ll need to reference the following assemblies:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;StorageClient.dll &lt;/li&gt;    &lt;li&gt;System.Data.Services.Client.dll &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;You’ll also need to reference your &lt;font color="#008080"&gt;DataServiceContext&lt;/font&gt; implementation. For demo purposes I am pulling data from my &lt;a href="http://blogs.conchango.com/jamiethomson/archive/2009/05/06/tweetpoll-my-first-windows-azure-application-is-live.aspx"&gt;Tweetpoll&lt;/a&gt; application so I’m referencing the assembly containing my &lt;font color="#008080"&gt;TweetPollDataServiceContext&lt;/font&gt; class - TweetPoll.dll:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.conchango.com/blogs/jamiethomson/image_2E1549B7.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://blogs.conchango.com/blogs/jamiethomson/image_thumb_4ABE98FF.png" width="658" height="280" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;We also need to import the namespaces into LINQPad. You’ll need the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Microsoft.Samples.ServiceHosting.StorageClient &lt;/li&gt;    &lt;li&gt;System.Data.Services.Client &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;plus whichever namespace holds your &lt;font color="#008080"&gt;DataServiceContext&lt;/font&gt; implementation:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.conchango.com/blogs/jamiethomson/image_3ACF543B.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://blogs.conchango.com/blogs/jamiethomson/image_thumb_571C965B.png" width="658" height="280" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Thereafter you just need to write some code. You need to supply the following:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Your Azure storage account name &lt;/li&gt;    &lt;li&gt;Your Azure storage shared key &lt;/li&gt;    &lt;li&gt;The name of your DataServiceContext implementation &lt;/li&gt;    &lt;li&gt;A LINQ query &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Here’s my code:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;var accountName = &lt;span style="color:#006080;"&gt;&amp;quot;jamiekt&amp;quot;&lt;/span&gt;;  &lt;span style="color:#008000;"&gt;// 1) Enter your storage account name&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;var sharedKey = &lt;span style="color:#006080;"&gt;&amp;quot;smXblLn+UgXR6ysbIhoeTfE3dyOZhAaONXOP/SUawRSLzCWwDXrhkpRG45A5aeAP5IEjSBEN2mEmPM8O5HnWGQ==&amp;quot;&lt;/span&gt;; &lt;span style="color:#008000;"&gt;// 2) SharedKey&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;var uri = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; System.Uri(&lt;span style="color:#006080;"&gt;&amp;quot;http://table.core.windows.net/&amp;quot;&lt;/span&gt;);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;var tableAccountInfo = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; StorageAccountInfo(uri, &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;, accountName, sharedKey);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;var svc = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; TweetPollDataServiceContext(tableAccountInfo); &lt;span style="color:#008000;"&gt;// 3) Specify your DataServiceContext&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#008000;"&gt;// 4) Supply your query&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;var query = from row &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; svc.Table &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;                       select row;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;query.Dump();&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;br /&gt;And here are the results in LINQPad:&lt;/div&gt;

&lt;div&gt;&lt;a href="http://blogs.conchango.com/blogs/jamiethomson/image12_363511FF.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://blogs.conchango.com/blogs/jamiethomson/image12_thumb_05525A94.png" width="708" height="749" /&gt;&lt;/a&gt; &lt;/div&gt;

&lt;div&gt;Hope that helps!!!&lt;/div&gt;

&lt;p&gt;&lt;a href="http://twitter.com/jamiet"&gt;@Jamiet&lt;/a&gt;&lt;/p&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=15756" width="1" height="1"&gt;</description><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/windows+azure/default.aspx">windows azure</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/azure/default.aspx">azure</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/LINQPad/default.aspx">LINQPad</category><category domain="http://consultingblogs.emc.com/jamiethomson/archive/tags/LINQ/default.aspx">LINQ</category></item></channel></rss>