<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://agilebi.com/cs/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">BI Thoughts and Theories</title><subtitle type="html" /><id>http://agilebi.com/cs/blogs/jwelch/atom.aspx</id><link rel="alternate" type="text/html" href="http://agilebi.com/cs/blogs/jwelch/default.aspx" /><link rel="self" type="application/atom+xml" href="http://agilebi.com/cs/blogs/jwelch/atom.aspx" /><generator uri="http://communityserver.org" version="2.1.61129.2">Community Server</generator><updated>2009-08-25T22:44:25Z</updated><entry><title>Developer Gaps</title><link rel="alternate" type="text/html" href="http://agilebi.com/cs/blogs/jwelch/archive/2010/03/18/developer-gaps.aspx" /><id>http://agilebi.com/cs/blogs/jwelch/archive/2010/03/18/developer-gaps.aspx</id><published>2010-03-18T01:40:07Z</published><updated>2010-03-18T01:40:07Z</updated><content type="html">&lt;p&gt;I’ve been meaning to post about this ever since I saw Jamie’s post on “&lt;a href="http://sqlblog.com/blogs/jamie_thomson/archive/2010/01/13/the-sql-developer-gap-warning-rant-coming-up.aspx"&gt;The SQL Developer Gap&lt;/a&gt;”. I couldn’t agree more with what Jamie expressed. Prior to getting into serious BI development, I was primarily an application developer. This was at a time when agile development was becoming very popular. As part of that, refactoring, test driven development, continuous integration, and automated unit testing were becoming accepted as good software engineering practices, and tool support was coming along very quickly. &lt;/p&gt;  &lt;p&gt;Then I switched over to BI development in the SQL Server 7 time frame. In a lot of ways, it was like going back to the dark ages. No refactoring support, no automated testing, no concept of builds. Nothing significant changed until SQL Server 2005, when tools like SSIS and SSAS took their first steps toward becoming more “developer friendly” by leveraging Visual Studio to easily integrate into source control and the beginnings of multi-developer support. However, there haven’t really been any improvements in this since 2005. Refactoring, automated testing, automated builds, etc., can all be done, but they are painful and time consuming to set up, and require a fair amount of specialized knowledge to do correctly. In addition, these are all skills that the average BI developer usually doesn’t posses.&lt;/p&gt;  &lt;p&gt;To join in Jamie’s rant, this is something that has aggravated me increasingly over the last few years. In many ways, BI is ideally suited to an agile approach and developer tools that increase productivity – requirements shift on the whim of the business, you need to deliver quickly and often, and you need easy mechanisms to confirm that what you are delivering provides the correct results. There are many tasks in developing BI solutions that are repetitive and could be easily automated, if only the tools provided better support for it. And developer productivity using the SQL Server BI tools hasn’t seen a significant increase since 2005.&lt;/p&gt;  &lt;p&gt;I’m spending a fair amount of my time these days working in Visual Studio, where I have the luxury of a built in unit testing tool, the capability to switch between visual editing and text editing depending on which makes the most sense, the ability to easily do a diff between two versions in source control, a full undo-redo stack, etc. And I get to use add-ins like &lt;a href="http://www.jetbrains.com/resharper/"&gt;ReSharper&lt;/a&gt; (a fantastic tool that I can’t recommend enough). It really highlights the difference between developing traditional applications and BI applications these days.&lt;/p&gt;  &lt;p&gt;That’s part of the reason I joined Varigence, where I have the opportunity to actually help developers deliver BI solutions faster and better. Our approach makes it much easier to support the same features that you see in traditional application development tools. I’ve been pretty pleased to see how easy it is for us to add productivity features to our tools – honestly, it makes me wonder why BI developers had to wait this long for these features to be available in the tools we use on a daily basis.&lt;/p&gt;&lt;img src="http://agilebi.com/cs/aggbug.aspx?PostID=421" width="1" height="1"&gt;</content><author><name>jwelch</name><uri>http://agilebi.com/cs/members/jwelch.aspx</uri></author><category term="SSIS" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/SSIS/default.aspx" /><category term="SSAS" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/SSAS/default.aspx" /><category term="Unit Testing" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/Unit+Testing/default.aspx" /><category term="Agile Practices" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/Agile+Practices/default.aspx" /></entry><entry><title>SQL Saturday #33 – Coming Up Next Weekend</title><link rel="alternate" type="text/html" href="http://agilebi.com/cs/blogs/jwelch/archive/2010/02/26/sql-saturday-33-coming-up-next-weekend.aspx" /><id>http://agilebi.com/cs/blogs/jwelch/archive/2010/02/26/sql-saturday-33-coming-up-next-weekend.aspx</id><published>2010-02-26T02:42:53Z</published><updated>2010-02-26T02:42:53Z</updated><content type="html">&lt;p&gt;The &lt;a href="http://www.sqlsaturday.com/33/eventhome.aspx"&gt;Charlotte SQL Saturday&lt;/a&gt; is coming up next weekend, March 6th. There is a great lineup of speakers presenting, and we are approaching capacity for the event, so get registered soon, if you haven’t already. It’s going to be a great day – free SQL training from a lot of well-known, well-respected names, a number of our local community members, and some Microsoft people as well. &lt;/p&gt;  &lt;p&gt;I’ll be presenting on Creating Custom Components for SSIS – a great way to extend the out-of-the-box functionality of Integration Services, and on Vulcan, an open source framework for modeling and generating portions of your BI solution. &lt;/p&gt;  &lt;p&gt;We’re got a &lt;a href="http://www.sqlsaturday.com/33/sponsors.aspx"&gt;great set of sponsors&lt;/a&gt;, including &lt;a href="http://www.sqlsentry.net"&gt;SQL Sentry&lt;/a&gt; (thanks Peter and Greg for all the work and support for the event – without them, it wouldn’t be what it is today – and if you are using SSAS, you really should check out &lt;a href="http://sqlsentry.net/performance-advisor/sql-server-analysis-services.asp"&gt;Performance Advisor for Analysis Services&lt;/a&gt;), and &lt;a href="http://www.microsoft.com"&gt;Microsoft&lt;/a&gt;, who’s providing access to their campus for the event, among other things. &lt;a href="http://www.quest.com/"&gt;Quest&lt;/a&gt;, &lt;a href="http://www.confio.com/"&gt;Confio&lt;/a&gt;, and &lt;a href="http://www.red-gate.com/about/community_relations/sql_saturday.htm?utm_source=ug&amp;amp;utm_medium=uglogo&amp;amp;utm_content=charlotte&amp;amp;utm_campaign=redgate"&gt;Red Gate&lt;/a&gt; provide some great tools for administering and developing for SQL Server, &lt;a href="http://www.intellinet.com/"&gt;Intellinet&lt;/a&gt; provides services for SQL Server, and &lt;a href="http://www.cozyroc.com/"&gt;CozyRoc&lt;/a&gt; provides a great set of SSIS tasks and components.&lt;/p&gt;&lt;img src="http://agilebi.com/cs/aggbug.aspx?PostID=405" width="1" height="1"&gt;</content><author><name>jwelch</name><uri>http://agilebi.com/cs/members/jwelch.aspx</uri></author><category term="Presentations" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/Presentations/default.aspx" /></entry><entry><title>Slides From the Columbia Code Camp</title><link rel="alternate" type="text/html" href="http://agilebi.com/cs/blogs/jwelch/archive/2010/02/02/slides-from-the-columbia-code-camp.aspx" /><id>http://agilebi.com/cs/blogs/jwelch/archive/2010/02/02/slides-from-the-columbia-code-camp.aspx</id><published>2010-02-02T00:41:00Z</published><updated>2010-02-02T00:41:00Z</updated><content type="html">&lt;P&gt;Thanks to everyone who made it out to the Columbia Code Camp this weekend, even with the sleet and snow in the area. I had a number of requests for the slides from my presentations, so I’ve uploaded them to my SkyDrive.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://cid-71c6f14e3c205217.skydrive.live.com/self.aspx/Public/Introduction%20to%20SSIS/Introduction%20to%20SSIS.pdf"&gt;Introduction to SSIS&lt;/A&gt;&amp;nbsp;(&lt;A href="http://speakerrate.com/talks/2082-introduction-to-ssis"&gt;SpeakerRate link&lt;/A&gt;)&lt;/P&gt;
&lt;P&gt;&lt;A href="http://cid-71c6f14e3c205217.skydrive.live.com/self.aspx/Public/Creating%20Custom%20Components%20for%20SSIS/Creating%20Custom%20Components%20for%20SSIS.pdf"&gt;Creating Custom Components for SSIS&lt;/A&gt;&amp;nbsp;(&lt;A href="http://speakerrate.com/talks/2083-creating-custom-components-in-ssis"&gt;SpeakerRate link&lt;/A&gt;) &amp;nbsp;(the sample component used in this presentation is on CodePlex in the &lt;A href="http://ssisctc.codeplex.com/"&gt;Community Tasks and Components project&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Thanks again for attending, and if you have any follow up questions, please leave them in the comments.&lt;/P&gt;&lt;img src="http://agilebi.com/cs/aggbug.aspx?PostID=400" width="1" height="1"&gt;</content><author><name>jwelch</name><uri>http://agilebi.com/cs/members/jwelch.aspx</uri></author><category term="SSIS" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/SSIS/default.aspx" /><category term="Presentations" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/Presentations/default.aspx" /></entry><entry><title>Slides From “Processing Flat Files with SSIS”</title><link rel="alternate" type="text/html" href="http://agilebi.com/cs/blogs/jwelch/archive/2010/01/15/slides-from-processing-flat-files-with-ssis.aspx" /><id>http://agilebi.com/cs/blogs/jwelch/archive/2010/01/15/slides-from-processing-flat-files-with-ssis.aspx</id><published>2010-01-15T02:53:38Z</published><updated>2010-01-15T02:53:38Z</updated><content type="html">&lt;p&gt;Thanks to the &lt;a href="http://columbiadevelopers.org/"&gt;Columbia Enterprise Developer’s Guild&lt;/a&gt; for letting me present last night. The audience was great, and I got a lot of good questions. Several people asked if the samples could be made available, and I also had a request to post the slides for some people who weren’t able to make it. So, here they are. I’ve posted them to my &lt;a href="http://cid-71c6f14e3c205217.skydrive.live.com/self.aspx/Public/Processing%20Flat%20Files%20with%20SSIS/FlatFileExamples.zip"&gt;SkyDrive here&lt;/a&gt;. If you have any questions or comments, please feel free to leave them here.&lt;/p&gt;&lt;img src="http://agilebi.com/cs/aggbug.aspx?PostID=397" width="1" height="1"&gt;</content><author><name>jwelch</name><uri>http://agilebi.com/cs/members/jwelch.aspx</uri></author><category term="SSIS" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/SSIS/default.aspx" /><category term="Flat Files" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/Flat+Files/default.aspx" /><category term="Presentations" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/Presentations/default.aspx" /></entry><entry><title>A New Year and Upcoming Presentations</title><link rel="alternate" type="text/html" href="http://agilebi.com/cs/blogs/jwelch/archive/2010/01/09/a-new-year-and-upcoming-presentations.aspx" /><id>http://agilebi.com/cs/blogs/jwelch/archive/2010/01/09/a-new-year-and-upcoming-presentations.aspx</id><published>2010-01-09T03:18:18Z</published><updated>2010-01-09T03:18:18Z</updated><content type="html">&lt;p&gt;It’s a new year, and already a lot going on. The new job is going well, but keeping me extremely busy. I’ve got several upcoming presentations, and there’s a &lt;a href="http://sqlsaturday.com/33/eventhome.aspx"&gt;SQL Saturday event&lt;/a&gt; planned for Charlotte in March that I’m helping organize. I’m also happy to say that my MVP status was re-awarded for 2010. &lt;/p&gt;  &lt;p&gt;I have an upcoming presentation at the &lt;a href="http://columbiadevelopers.org/"&gt;Columbia Enterprise Developers Guild&lt;/a&gt;, next Wednesday the 13th. The presentation will be on handling flat files in SSIS.&lt;/p&gt;  &lt;h3&gt;Processing Flat Files with SSIS&lt;/h3&gt;  &lt;p&gt;When doing data integration, a common requirement is to work with flat files, whether for importing data into a system from an external source, or to export it to provide to other systems. SQL Server Integration Services (SSIS) supports flat files, but there can be a number of challenges when working with them. This is particularly true if your flat files have multiple data formats contained in a single file, the data has complex formatting, or the files have inconsistent formatting. This session will help you to be more efficient when working with these types of files. You’ll learn to handle missing delimiters in the files, and parsing files that have multiple data formats. You’ll also see how to produce complex output formats, like headers and footers that contain summary information.&lt;/p&gt;  &lt;p&gt;I’ll also be doing a couple of presentations at the &lt;a href="http://columbiacodecamp.com/"&gt;Columbia Code Camp&lt;/a&gt; on January 30th.&lt;/p&gt;  &lt;h3&gt;Creating Custom Components for SSIS&lt;/h3&gt;  &lt;p&gt;SSIS data flows are great tools for moving data. But what if you need to go beyond the out-of-the-box components provided with SSIS? Custom components are a great way to encapsulate and reuse functionality for the data flow in SSIS. We will discuss what it takes to create and deploy custom components in SSIS, review the pros and cons of using custom components instead of scripts, and discuss some of the common challenges and issues with creating them.&lt;/p&gt;  &lt;h3&gt;Introduction to SSIS&lt;/h3&gt;  &lt;p&gt;SQL Server Integration Services is a tool provided with SQL Server for moving data between data stores. It is the successor to DTS, but there are many fundamental changes in how SSIS works. This session will provide an overview of SSIS, with a focus on the key elements of SSIS that you need to know to get the most use out of it. This session will help developers efficiently use SSIS when they need to move data around the organization.&lt;/p&gt;  &lt;p&gt;If you happen to be in the area, please drop by for these presentations.&lt;/p&gt;&lt;img src="http://agilebi.com/cs/aggbug.aspx?PostID=395" width="1" height="1"&gt;</content><author><name>jwelch</name><uri>http://agilebi.com/cs/members/jwelch.aspx</uri></author><category term="SSIS" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/SSIS/default.aspx" /><category term="Presentations" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/Presentations/default.aspx" /></entry><entry><title>Performance of Raw Files vs. Flat Files</title><link rel="alternate" type="text/html" href="http://agilebi.com/cs/blogs/jwelch/archive/2009/12/14/performance-of-raw-files-vs-flat-files.aspx" /><id>http://agilebi.com/cs/blogs/jwelch/archive/2009/12/14/performance-of-raw-files-vs-flat-files.aspx</id><published>2009-12-14T02:00:34Z</published><updated>2009-12-14T02:00:34Z</updated><content type="html">&lt;p&gt;It’s pretty well accepted that raw files in SSIS are a very fast means of getting data in and out of the pipeline. &lt;a href="http://sqlblog.com/blogs/jamie_thomson/"&gt;Jamie Thomson&lt;/a&gt; has referenced &lt;a href="http://consultingblogs.emc.com/jamiethomson/archive/tags/raw+files/default.aspx"&gt;the use of raw files a number of times&lt;/a&gt; and &lt;a href="http://toddmcdermid.blogspot.com/"&gt;Todd McDermid&lt;/a&gt; recently posted about &lt;a href="http://toddmcdermid.blogspot.com/2009/12/using-raw-files-for-staging-data-in.html"&gt;using them for staging data&lt;/a&gt;. It occurred to me, that even though I’d always heard they were faster than other options, I’d never actually tested it to see exactly how much of a difference it would make. So, below I’ve posted some admitted unscientific performance testing between raw files and flat (or text) files.&lt;/p&gt;  &lt;p&gt;I tested two variations of flat files, delimited and ragged right. The delimited file was configured with a vertical bar (|) as the column delimiter and CR/LF as the row delimiter. The ragged right file was configured as a fixed width with row delimiters – each column had a fixed width, and a final, zero-width column was appended with CR/LF as the delimiter. The same data was used for each test, the following columns being defined:&lt;/p&gt;  &lt;table cellspacing="0" cellpadding="0"&gt;     &lt;tr&gt;       &lt;td&gt;Name&lt;/td&gt;        &lt;td&gt;Data Type&lt;/td&gt;        &lt;td&gt;Precision&lt;/td&gt;        &lt;td&gt;Scale&lt;/td&gt;        &lt;td&gt;Length&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;TestInt32&lt;/td&gt;        &lt;td&gt;DT_I4&lt;/td&gt;        &lt;td&gt;0&lt;/td&gt;        &lt;td&gt;0&lt;/td&gt;        &lt;td&gt;0&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;TestString&lt;/td&gt;        &lt;td&gt;DT_STR&lt;/td&gt;        &lt;td&gt;0&lt;/td&gt;        &lt;td&gt;0&lt;/td&gt;        &lt;td&gt;50&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;TestBool&lt;/td&gt;        &lt;td&gt;DT_BOOL&lt;/td&gt;        &lt;td&gt;0&lt;/td&gt;        &lt;td&gt;0&lt;/td&gt;        &lt;td&gt;0&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;TestCurrency&lt;/td&gt;        &lt;td&gt;DT_CY&lt;/td&gt;        &lt;td&gt;0&lt;/td&gt;        &lt;td&gt;0&lt;/td&gt;        &lt;td&gt;0&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;TestDBTimestamp&lt;/td&gt;        &lt;td&gt;DT_DBTIMESTAMP&lt;/td&gt;        &lt;td&gt;0&lt;/td&gt;        &lt;td&gt;0&lt;/td&gt;        &lt;td&gt;0&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;TestWString&lt;/td&gt;        &lt;td&gt;DT_WSTR&lt;/td&gt;        &lt;td&gt;0&lt;/td&gt;        &lt;td&gt;0&lt;/td&gt;        &lt;td&gt;50&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;TestNumeric&lt;/td&gt;        &lt;td&gt;DT_NUMERIC&lt;/td&gt;        &lt;td&gt;18&lt;/td&gt;        &lt;td&gt;6&lt;/td&gt;        &lt;td&gt;0&lt;/td&gt;     &lt;/tr&gt;   &lt;/table&gt;  &lt;p&gt;One thing to note is that when importing from flat files, everything was imported as strings, to avoid any data conversion issues. This is one of the strengths of raw files – no data conversion necessary. But for this test, I was primarily looking at speed of getting the data on and off disk. I also looked at the difference in file sizes between the formats.&lt;/p&gt;  &lt;p&gt;I tested each option with 500,000, 1 million, and 10 million rows. I ran each one 4 times for each row count, and discarded the first run to offset the effects of file caching. The results of the runs were averaged for comparison.&lt;/p&gt;  &lt;p&gt;When writing files, there’s no big surprises between the options. raw files are faster on 10 million rows by 9.8 seconds. The difference on smaller numbers of rows is pretty insignificant. Here’s a chart showing the times (the raw data is at the end of the post):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.agilebi.com/images/RAWFilesvs.FlatFIles_11217/image.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://www.agilebi.com/images/RAWFilesvs.FlatFIles_11217/image_thumb.png" width="485" height="246" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Reading files did show a difference that I didn’t expect. Read speeds on raw files and delimited files are fairly comparable, with raw files still having the edge in speed. However, reads on ragged right files are significantly slower – well over twice as slow when compared to raw files.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.agilebi.com/images/RAWFilesvs.FlatFIles_11217/image_3.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://www.agilebi.com/images/RAWFilesvs.FlatFIles_11217/image_thumb_3.png" width="485" height="294" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;File sizes were also as expected, with delimited files having a slight edge over raw files, likely because the string values I used were not all 50 characters in length.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.agilebi.com/images/RAWFilesvs.FlatFIles_11217/image_4.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://www.agilebi.com/images/RAWFilesvs.FlatFIles_11217/image_thumb_4.png" width="485" height="294" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;In summary, it’s clear that raw files have an advantage in speed. However, the differences weren’t as large as I was expecting, except in the case of ragged right files. So, in general, using raw files are best for performance, but if you are dealing with row counts of less than 1 million rows, it’s not a huge difference unless you are really concerned with performance. Of course, there are plenty of other differences between the formats, and I’d encourage you to research them before making a decision.&lt;/p&gt;  &lt;p&gt;Here’s the raw data on the number of seconds to produce each file:&lt;/p&gt;  &lt;table cellspacing="0" cellpadding="0"&gt;     &lt;tr&gt;       &lt;td&gt;&amp;#160;&lt;/td&gt;        &lt;td&gt;&lt;strong&gt;500,000&lt;/strong&gt;&lt;/td&gt;        &lt;td&gt;&lt;strong&gt;1,000,000&lt;/strong&gt;&lt;/td&gt;        &lt;td&gt;&lt;strong&gt;10,000,000&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Write To Delimited&lt;/td&gt;        &lt;td&gt;2.61&lt;/td&gt;        &lt;td&gt;5.16&lt;/td&gt;        &lt;td&gt;47.02&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Write To Ragged&lt;/td&gt;        &lt;td&gt;2.66&lt;/td&gt;        &lt;td&gt;5.31&lt;/td&gt;        &lt;td&gt;49.03&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Write To Raw&lt;/td&gt;        &lt;td&gt;2.21&lt;/td&gt;        &lt;td&gt;4.23&lt;/td&gt;        &lt;td&gt;39.21&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;&amp;#160;&lt;/td&gt;        &lt;td&gt;&lt;strong&gt;500,000&lt;/strong&gt;&lt;/td&gt;        &lt;td&gt;&lt;strong&gt;1,000,000&lt;/strong&gt;&lt;/td&gt;        &lt;td&gt;&lt;strong&gt;10,000,000&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Read From Delimited&lt;/td&gt;        &lt;td&gt;0.77&lt;/td&gt;        &lt;td&gt;1.52&lt;/td&gt;        &lt;td&gt;16.59&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Read From Ragged&lt;/td&gt;        &lt;td&gt;2.74&lt;/td&gt;        &lt;td&gt;5.89&lt;/td&gt;        &lt;td&gt;35.39&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Read From Raw&lt;/td&gt;        &lt;td&gt;0.60&lt;/td&gt;        &lt;td&gt;1.08&lt;/td&gt;        &lt;td&gt;10.03&lt;/td&gt;     &lt;/tr&gt;   &lt;/table&gt;  &lt;p&gt;and the file size in KB for each:&lt;/p&gt;  &lt;table cellspacing="0" cellpadding="0"&gt;     &lt;tr&gt;       &lt;td&gt;&amp;#160;&lt;/td&gt;        &lt;td&gt;&lt;strong&gt;500,000&lt;/strong&gt;&lt;/td&gt;        &lt;td&gt;&lt;strong&gt;1,000,000&lt;/strong&gt;&lt;/td&gt;        &lt;td&gt;&lt;strong&gt;10,000,000&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Delimited&lt;/td&gt;        &lt;td&gt;44,624&lt;/td&gt;        &lt;td&gt;89,792&lt;/td&gt;        &lt;td&gt;946,745&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Ragged&lt;/td&gt;        &lt;td&gt;92,286&lt;/td&gt;        &lt;td&gt;184,571&lt;/td&gt;        &lt;td&gt;1,845,704&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Raw&lt;/td&gt;        &lt;td&gt;47,039&lt;/td&gt;        &lt;td&gt;94,402&lt;/td&gt;        &lt;td&gt;973,308&lt;/td&gt;     &lt;/tr&gt;   &lt;/table&gt;  &lt;p&gt;Please let me know if you’d like more details or have any questions. &lt;/p&gt;&lt;img src="http://agilebi.com/cs/aggbug.aspx?PostID=388" width="1" height="1"&gt;</content><author><name>jwelch</name><uri>http://agilebi.com/cs/members/jwelch.aspx</uri></author><category term="SSIS" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/SSIS/default.aspx" /><category term="Performance" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/Performance/default.aspx" /></entry><entry><title>New Path, Same Focus</title><link rel="alternate" type="text/html" href="http://agilebi.com/cs/blogs/jwelch/archive/2009/12/05/new-path-same-focus.aspx" /><id>http://agilebi.com/cs/blogs/jwelch/archive/2009/12/05/new-path-same-focus.aspx</id><published>2009-12-05T03:40:08Z</published><updated>2009-12-05T03:40:08Z</updated><content type="html">&lt;p&gt;I’ve worked with &lt;a href="http://www.mariner-usa.com"&gt;Mariner&lt;/a&gt; for almost 12 years. It’s been a very good journey, with many great experiences. I’ve worked with a lot of great people, and delivered some really interesting BI solutions to clients in a number of industries. One aspect of my job that I always particularly enjoyed was helping developers be more productive when creating BI solutions, and reducing the repetitive (read: “boring”) aspects of developing solutions on the Microsoft stack. &lt;/p&gt;  &lt;p&gt;Recently, a new opportunity to focus more heavily on that came along. As a result, after a long and enjoyable career with Mariner doing business intelligence consulting, I am taking a new position with &lt;a href="http://www.varigence.com/"&gt;Varigence&lt;/a&gt;, a company that is producing tools that will make implementing BI solutions faster and easier, as well as introduce new capabilities and better integration into the Microsoft BI stack.&lt;/p&gt;  &lt;p&gt;I’m really looking forward to the new role and the new experiences it will offer. I will continue to be heavily involved in Microsoft BI, so I plan to maintain this blog and continue speaking and writing on it as often as often as possible.&lt;/p&gt;&lt;img src="http://agilebi.com/cs/aggbug.aspx?PostID=383" width="1" height="1"&gt;</content><author><name>jwelch</name><uri>http://agilebi.com/cs/members/jwelch.aspx</uri></author><category term="BI" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/BI/default.aspx" /><category term="Speaking" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/Speaking/default.aspx" /><category term="Presentations" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/Presentations/default.aspx" /></entry><entry><title>Sample Files for Introduction To Analysis Services 2008</title><link rel="alternate" type="text/html" href="http://agilebi.com/cs/blogs/jwelch/archive/2009/12/04/sample-files-for-introduction-to-analysis-services-2008.aspx" /><id>http://agilebi.com/cs/blogs/jwelch/archive/2009/12/04/sample-files-for-introduction-to-analysis-services-2008.aspx</id><published>2009-12-04T16:44:59Z</published><updated>2009-12-04T16:44:59Z</updated><content type="html">&lt;p&gt;We had good turnout at the Greenville, SC &lt;a href="http://ssig.org/"&gt;SSIG&lt;/a&gt; on Tuesday. If you attended, I hope you enjoyed the presentation. After the meeting, I promised several attendees that I would make the samples developed during the demo available, and &lt;a href="http://cid-695cdda853ce07ee.skydrive.live.com/self.aspx/Public/BI%20Thoughts%20and%20Theories/SSIG%20-%20Intro%20to%20SSAS%202008.zip"&gt;here they are&lt;/a&gt;. The zip includes both the SSAS project files, and a backup the sample database that the cube was built on. Both are done using the 2008 version of SQL Server.&lt;/p&gt;  &lt;p&gt;If you have any questions about , please post them in the comments.&lt;/p&gt;&lt;img src="http://agilebi.com/cs/aggbug.aspx?PostID=382" width="1" height="1"&gt;</content><author><name>jwelch</name><uri>http://agilebi.com/cs/members/jwelch.aspx</uri></author><category term="Presentations" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/Presentations/default.aspx" /><category term="SSAS 2008" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/SSAS+2008/default.aspx" /></entry><entry><title>Presenting At SSIG in Greenville, SC</title><link rel="alternate" type="text/html" href="http://agilebi.com/cs/blogs/jwelch/archive/2009/11/29/presenting-at-ssig-in-greenville-sc.aspx" /><id>http://agilebi.com/cs/blogs/jwelch/archive/2009/11/29/presenting-at-ssig-in-greenville-sc.aspx</id><published>2009-11-29T20:35:22Z</published><updated>2009-11-29T20:35:22Z</updated><content type="html">&lt;p&gt;I’ll be doing a presentation on Analysis Services at the &lt;a href="http://ssig.org/"&gt;SQL Server Innovators Guild&lt;/a&gt; in Greenville, SC on Tuesday, Dec. 1st. I’ll be delivering an introduction to SSAS, with lots of demos. If you are interested in attending, please &lt;a href="http://bit.ly/T8erq"&gt;register here&lt;/a&gt;. It’s a presentation that I’ve done a few times now, but because it’s mostly demo, something new and interesting always comes up.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Introduction to Analysis Services 2008&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;This session is intended to introduce database developers to Analysis Services 2008, with a focus on being able to quickly construct usable OLAP cubes. This presentation will be light on slides, and heavy on demonstrating how to perform the steps to create the cubes. During this session, we will cover the creation of a new cube from an existing database step by step. We will also highlight the reasons for using Analysis Services, and applicable scenarios for using it.&lt;/p&gt;&lt;img src="http://agilebi.com/cs/aggbug.aspx?PostID=376" width="1" height="1"&gt;</content><author><name>jwelch</name><uri>http://agilebi.com/cs/members/jwelch.aspx</uri></author><category term="Presentations" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/Presentations/default.aspx" /><category term="SSAS 2008" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/SSAS+2008/default.aspx" /></entry><entry><title>SSIS 101: Viewing Variable Values at Runtime</title><link rel="alternate" type="text/html" href="http://agilebi.com/cs/blogs/jwelch/archive/2009/11/29/ssis-101-viewing-variable-values-at-runtime.aspx" /><id>http://agilebi.com/cs/blogs/jwelch/archive/2009/11/29/ssis-101-viewing-variable-values-at-runtime.aspx</id><published>2009-11-29T17:00:00Z</published><updated>2009-11-29T17:00:00Z</updated><content type="html">&lt;p&gt;One of the common problems that beginners have with SSIS is debugging errors involving variables. One example of this occurs when a package uses a Foreach Loop container. These are often used to set a variable value differently for each iteration of a loop. If something fails during the loop, you might want to check the value of the variable in order to determine what went wrong. &lt;/p&gt;  &lt;p&gt;Fortunately, this is pretty easy to accomplish in SSIS. You can see the value of any package variable in BIDS when you debug the package by following the steps below:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;First, set a breakpoint on a task where you'd like to check the current variable values. You can set a breakpoint by right-clicking on the task and choosing Edit Breakpoints.&lt;a href="http://www.agilebi.com/images/ViewingVariableValuesatRuntime_10D89/image.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://www.agilebi.com/images/ViewingVariableValuesatRuntime_10D89/image_thumb.png" width="366" height="293" /&gt;&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Choose OnPreExecute to see values before the task executes and OnPostExecute to see them after execution. Click OK after enabling the breakpoint.     &lt;br /&gt;&lt;a href="http://www.agilebi.com/images/ViewingVariableValuesatRuntime_10D89/image_3.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://www.agilebi.com/images/ViewingVariableValuesatRuntime_10D89/image_thumb_3.png" width="616" height="454" /&gt;&lt;/a&gt;&amp;#160;&lt;/li&gt;    &lt;li&gt;Run the package in debug mode (press F5) in Visual Studio. The package will run until the breakpoint is hit.     &lt;br /&gt;&lt;a href="http://www.agilebi.com/images/ViewingVariableValuesatRuntime_10D89/image_4.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://www.agilebi.com/images/ViewingVariableValuesatRuntime_10D89/image_thumb_4.png" width="195" height="164" /&gt;&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Once execution stops at the breakpoint, open the Locals window (Ctrl+Alt+V, L or Debug..Windows..Locals)     &lt;br /&gt;&lt;a href="http://www.agilebi.com/images/ViewingVariableValuesatRuntime_10D89/image_5.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://www.agilebi.com/images/ViewingVariableValuesatRuntime_10D89/image_thumb_5.png" width="465" height="148" /&gt;&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Expand the Variable node in the Locals window. You can see the current values for all your variables, including system variables, in this window. You may have to scroll down to see your variables in the list     &lt;br /&gt;&lt;a href="http://www.agilebi.com/images/ViewingVariableValuesatRuntime_10D89/image_6.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://www.agilebi.com/images/ViewingVariableValuesatRuntime_10D89/image_thumb_6.png" width="622" height="204" /&gt;&lt;/a&gt;&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;This is a useful technique for troubleshooting packages that use variables, particularly if the variable values are changed during package execution. &lt;/p&gt;&lt;img src="http://agilebi.com/cs/aggbug.aspx?PostID=377" width="1" height="1"&gt;</content><author><name>jwelch</name><uri>http://agilebi.com/cs/members/jwelch.aspx</uri></author><category term="SSIS 101" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/SSIS+101/default.aspx" /><category term="Debugging" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/Debugging/default.aspx" /></entry><entry><title>PASS Summit 2009</title><link rel="alternate" type="text/html" href="http://agilebi.com/cs/blogs/jwelch/archive/2009/10/30/pass-summit-2009.aspx" /><id>http://agilebi.com/cs/blogs/jwelch/archive/2009/10/30/pass-summit-2009.aspx</id><published>2009-10-30T16:02:16Z</published><updated>2009-10-30T16:02:16Z</updated><content type="html">&lt;p&gt;I’m really looking forward to the PASS Summit next week, and getting a chance to visit with a lot of the people in the community that I interact with on a regular basis. It’s going to be a really busy week, as there’s a lot of great sessions that I’m looking forward to attending, and a few things that I’m going to be delivering myself. &lt;/p&gt;  &lt;p&gt;A quick summary of where I’ll be during the conference:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Tuesday (11/3) at 11:45 – Hosting a table at the Birds of a Feather lunch, with the topic “Agile Development in BI”&lt;/li&gt;    &lt;li&gt;Wednesday (11/4) at 10:15 – Presenting “&lt;a href="http://summit2009.sqlpass.org/Agenda/ProgramSessions/SQLServerBIintheCloud.aspx"&gt;SQL Server BI in the Cloud&lt;/a&gt;”, which will focus on how SQL Azure can be leveraged for BI projects&lt;/li&gt;    &lt;li&gt;Wednesday (11/4) at 11:30 – I’ll be stopping in briefly at the &lt;a href="http://www.sqlservermvpdeepdives.com"&gt;SQL Server MVP Deep Dives&lt;/a&gt; book launch, and then sprinting to my next session.&lt;/li&gt;    &lt;li&gt;Wednesday (11/4) at 12:00 – Co-Presenting “&lt;a href="http://summit2009.sqlpass.org/Agenda/ProgramSessions/ChalkTalkMetadataDrivenETLCreatingDynamic.aspx"&gt;Metadata Driven ETL - Creating Dynamic Packages with Integration Services&lt;/a&gt;” with &lt;a href="http://blogs.msdn.com/mattm/"&gt;Matt Masson&lt;/a&gt; of the Microsoft SSIS team, where we’ll be talking about generating SSIS packages from code, so that the packages can change dynamically as your data does.&lt;/li&gt;    &lt;li&gt;Thursday (11/5) at 4:00 – Presenting “&lt;a href="http://summit2009.sqlpass.org/Agenda/ProgramSessions/UsingAgileDevelopmentTechniqueswithIntegratio.aspx"&gt;Using Agile Development Techniques with Integration Services&lt;/a&gt;”, which will discuss some of the ways agile practices like test driven development and continuous integration can be used with SSIS.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Outside of that, I’ll be around at other sessions, the evening events, and in the “Ask the Experts” area. Looking forward to seeing everyone there.&lt;/p&gt;&lt;img src="http://agilebi.com/cs/aggbug.aspx?PostID=369" width="1" height="1"&gt;</content><author><name>jwelch</name><uri>http://agilebi.com/cs/members/jwelch.aspx</uri></author><category term="PASS" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/PASS/default.aspx" /></entry><entry><title>SQL Server MVP Deep Dives</title><link rel="alternate" type="text/html" href="http://agilebi.com/cs/blogs/jwelch/archive/2009/10/06/sql-server-mvp-deep-dives.aspx" /><id>http://agilebi.com/cs/blogs/jwelch/archive/2009/10/06/sql-server-mvp-deep-dives.aspx</id><published>2009-10-06T00:39:50Z</published><updated>2009-10-06T00:39:50Z</updated><content type="html">&lt;p&gt;There’s a new book available for pre-order - “&lt;a href="http://www.sqlservermvpdeepdives.com"&gt;SQL Server MVP Deep Dives&lt;/a&gt;”. This book is a little unusual in that 53 MVPs came together to contribute 59 chapters to the book. Some of the best SQL Server authors in the world contributed chapters to it. I’m certainly not one of that group, but somehow, I managed to get included, and it’s a great honor to be in such good company. The book covers a wide variety of SQL Server topics, including:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;design&lt;/li&gt;    &lt;li&gt;development&lt;/li&gt;    &lt;li&gt;administration&lt;/li&gt;    &lt;li&gt;tuning and optimization&lt;/li&gt;    &lt;li&gt;and business intelligence (my personal favorite)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This book was a special project for the authors involved. 100% of the author royalties go to &lt;a href="http://www.warchild.org/"&gt;War Child International&lt;/a&gt;, which is a charity that works to help children affected by war across the world.&lt;/p&gt;  &lt;p&gt;So, if you like the idea of learning some interesting things about SQL Server and helping children at the same time, &lt;a href="http://www.sqlservermvpdeepdives.com"&gt;get this book&lt;/a&gt;. If you are attending the &lt;a href="http://summit2009.sqlpass.org/"&gt;PASS Summit&lt;/a&gt;, it will be available for purchase from the conference bookstore onsite. There will be a large number of the authors at the Summit (including me), so there will be plenty of opportunities to get your copy signed.&lt;/p&gt;&lt;img src="http://agilebi.com/cs/aggbug.aspx?PostID=361" width="1" height="1"&gt;</content><author><name>jwelch</name><uri>http://agilebi.com/cs/members/jwelch.aspx</uri></author><category term="PASS" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/PASS/default.aspx" /></entry><entry><title>Passing an Object from a Parent Package To a Child</title><link rel="alternate" type="text/html" href="http://agilebi.com/cs/blogs/jwelch/archive/2009/10/03/passing-an-object-from-a-parent-package-to-a-child.aspx" /><id>http://agilebi.com/cs/blogs/jwelch/archive/2009/10/03/passing-an-object-from-a-parent-package-to-a-child.aspx</id><published>2009-10-03T20:19:31Z</published><updated>2009-10-03T20:19:31Z</updated><content type="html">&lt;p&gt;Occasionally, you may run into the need to pass values between packages. In most cases, you can use a &lt;a href="http://technet.microsoft.com/en-us/library/ms345179.aspx"&gt;Parent Package Variable&lt;/a&gt; configuration to pass the value of a variable in the calling (or parent) package to the called (or child) package. However, Parent Package Variable configurations can’t be set up on variables of type Object. Fortunately, you can work around this pretty easily, thanks to the fact that the calling package variables are inherently accessible in the called packages.&amp;#160; &lt;/p&gt;  &lt;p&gt;I’ve set up a sample parent and child package to illustrate this. The parent package is straightforward. It uses an Execute SQL task to populate an object variable named TestVar with a recordset object, and then calls the child package.&lt;/p&gt;  &lt;table cellspacing="0" cellpadding="2"&gt;     &lt;tr&gt;       &lt;td&gt;&lt;a href="http://www.agilebi.com/images/PassinganObjectfromaParentPackageToaChil_E4EF/image.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://www.agilebi.com/images/PassinganObjectfromaParentPackageToaChil_E4EF/image_thumb.png" width="165" height="156" /&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td&gt;&lt;a href="http://www.agilebi.com/images/PassinganObjectfromaParentPackageToaChil_E4EF/image_3.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://www.agilebi.com/images/PassinganObjectfromaParentPackageToaChil_E4EF/image_thumb_3.png" width="299" height="94" /&gt;&lt;/a&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/table&gt;  &lt;p&gt;The child package has a Foreach Loop Container to iterate over the recordset object. It has a Script task that is used to copy the parent package’s variable (TestVar) to a local variable named LocalVar. This is the variable that the Foreach Loop is configured to use. Why copy the value? If you don’t have a local variable to reference in the Foreach Loop, it won’t validate properly.&lt;/p&gt;  &lt;table cellspacing="0" cellpadding="2"&gt;     &lt;tr&gt;       &lt;td&gt;&lt;a href="http://www.agilebi.com/images/PassinganObjectfromaParentPackageToaChil_E4EF/image_4.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://www.agilebi.com/images/PassinganObjectfromaParentPackageToaChil_E4EF/image_thumb_4.png" width="208" height="215" /&gt;&lt;/a&gt; &lt;/td&gt;        &lt;td&gt;&lt;a href="http://www.agilebi.com/images/PassinganObjectfromaParentPackageToaChil_E4EF/image_5.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://www.agilebi.com/images/PassinganObjectfromaParentPackageToaChil_E4EF/image_thumb_5.png" width="298" height="94" /&gt;&lt;/a&gt; &lt;/td&gt;     &lt;/tr&gt;   &lt;/table&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;The script in Copy Variable is pretty simple. It relies on the fact that you can reference parent package variables inherently, as they are included in the collection of variables accessible in the local package. The script just copies the value from one variable to the other, so that the Foreach Loop will have something to do.&lt;/p&gt;  &lt;pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;padding-bottom:5px;background-color:#fbfbfb;min-height:40px;padding-left:5px;width:650px;padding-right:5px;overflow:auto;border-top:#cecece 1px solid;border-right:#cecece 1px solid;padding-top:5px;"&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main()
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;{
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;    Variables vars = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;    Dts.VariableDispenser.LockForWrite(&amp;quot;&lt;span style="color:#8b0000;"&gt;User::LocalVar&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;    Dts.VariableDispenser.LockForRead(&amp;quot;&lt;span style="color:#8b0000;"&gt;User::TestVar&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;    Dts.VariableDispenser.GetVariables(&lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; vars);
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;    vars[&amp;quot;&lt;span style="color:#8b0000;"&gt;User::LocalVar&lt;/span&gt;&amp;quot;].Value = vars[&amp;quot;&lt;span style="color:#8b0000;"&gt;User::TestVar&lt;/span&gt;&amp;quot;].Value;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;    vars.Unlock();
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;    Dts.TaskResult = (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;)ScriptResults.Success;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Please note that for this to work, you cannot have a variable in the child package with the same name as the variable in the parent package. If you do, the local variable will hide the parent variable. Outside of that, this works really well for passing object values between packages. The same technique can also be used in reverse to send values back to the parent package, if you have that need.&lt;/p&gt;

&lt;p&gt;The sample has been &lt;a href="http://cid-695cdda853ce07ee.skydrive.live.com/self.aspx/Public/BI%20Thoughts%20and%20Theories/PassObjectFromParentToChild.zip"&gt;uploaded to my Skydrive&lt;/a&gt;. Let me know if you have any questions.&lt;/p&gt;&lt;img src="http://agilebi.com/cs/aggbug.aspx?PostID=359" width="1" height="1"&gt;</content><author><name>jwelch</name><uri>http://agilebi.com/cs/members/jwelch.aspx</uri></author><category term="Examples" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/Examples/default.aspx" /><category term="SSIS 2008" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/SSIS+2008/default.aspx" /><category term="Script" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/Script/default.aspx" /><category term="Configurations" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/Configurations/default.aspx" /></entry><entry><title>Implementing PerformUpgrade in Custom Components</title><link rel="alternate" type="text/html" href="http://agilebi.com/cs/blogs/jwelch/archive/2009/09/28/implementing-performupgrade-in-custom-components.aspx" /><id>http://agilebi.com/cs/blogs/jwelch/archive/2009/09/28/implementing-performupgrade-in-custom-components.aspx</id><published>2009-09-28T01:21:52Z</published><updated>2009-09-28T01:21:52Z</updated><content type="html">&lt;p&gt;If you develop custom components for SSIS, you may have the need to update them as you add new functionality. If you are just upgrading the functionality, but not changing the metadata, then you can simply recompile and redeploy the component. An example of this type of update would be changing the component to do additional warning or informational logging. The code has to be updated, but the metadata (the properties of the component, the settings for the inputs and outputs) was not modified.&lt;/p&gt;  &lt;p&gt;The other type of update involves changing the component’s metadata. Examples of this would be adding a new property to the component or adding new inputs or outputs. In this case, you could increment the assembly version of your component, but then you would have to remove the old one from any data flows, and then add the new one back in and reconnect it. Rather than forcing users of the component to go through that effort for every package that uses the component, you can implement the PerformUpgrade method on your component. The PerformUpgrade method will be called when the package is loaded and the current version of the component does not match the version stored in the package’s metadata. You can use this method to compare the current version of the component to the expected version, and adjust the metadata appropriately. &lt;/p&gt;  &lt;h3&gt;Setting the CurrentVersion&lt;/h3&gt;  &lt;p&gt;To use this, you have to tell SSIS what the current version of your component is. You do this by setting the CurrentVersion property in the DtsPipelineComponent attribute that can be set on the PipelineComponent class:&lt;/p&gt;  &lt;pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;padding-bottom:5px;background-color:#fbfbfb;min-height:40px;padding-left:5px;width:650px;padding-right:5px;overflow:auto;border-top:#cecece 1px solid;border-right:#cecece 1px solid;padding-top:5px;"&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;[DtsPipelineComponent(
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;    DisplayName = &amp;quot;&lt;span style="color:#8b0000;"&gt;Test Component&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;    ComponentType = ComponentType.Transform,
&lt;/pre&gt;&lt;pre style="background-color:#ffff00;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;    CurrentVersion = 1,
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;    NoEditor = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;)]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; TestComponent : PipelineComponent&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;The CurrentVersion property defaults to zero, so a value of 1 indicates that this component is now on it’s second version.&lt;/p&gt;

&lt;h3&gt;Performing the Upgrade&lt;/h3&gt;

&lt;p&gt;Next, you need to implement some code in the PerformUpgrade method. This consists of first getting the value of the CurrentVersion property, and at the end of the method, setting the version in the component’s metadata to the current version.&lt;/p&gt;

&lt;pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;padding-bottom:5px;background-color:#fbfbfb;min-height:40px;padding-left:5px;width:650px;padding-right:5px;overflow:auto;border-top:#cecece 1px solid;border-right:#cecece 1px solid;padding-top:5px;"&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;public override void PerformUpgrade(int pipelineVersion)
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;{
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;    &lt;span style="color:#008000;"&gt;// Obtain the current component version from the attribute.&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;    DtsPipelineComponentAttribute componentAttribute = 
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;      (DtsPipelineComponentAttribute)Attribute.GetCustomAttribute(this.GetType(), typeof(DtsPipelineComponentAttribute), false);
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;    int currentVersion = componentAttribute.CurrentVersion;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;    if (ComponentMetaData.Version &amp;lt; currentVersion)
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;        &lt;span style="color:#008000;"&gt;//Do the upgrade here&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;    &lt;span style="color:#008000;"&gt;// Update the saved component version metadata to the current version.&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;    ComponentMetaData.Version = currentVersion;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;}
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;The actual upgrade code can vary a good bit, from adding custom properties, adjusting the data types of outputs, or adding / deleting inputs or outputs. I won’t show the logic for these things here, but it’s pretty similar to the same code you’d use in &lt;a href="http://msdn.microsoft.com/en-us/library/ms135969.aspx"&gt;ProvideComponentProperties&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Handling Multiple Upgrades&lt;/h3&gt;

&lt;p&gt;The code above is based on the sample in &lt;a href="http://msdn.microsoft.com/en-us/library/ms345168.aspx"&gt;Books Online&lt;/a&gt;, but there’s a slight issue. Determining what upgrades need to be applied can be more complicated than simply comparing the current version to the ComponentMetaData version. Imagine that you have already upgraded the component from version 0 to version 1, by adding a new property. Now, you discover a need to add another new property, which will result in version 2. What do you do about the property added in version 1? You don’t want to add it twice for components that have already been upgraded to version 1. But it’s also possibly that not all packages have been upgraded from version 0 yet, so for those you need to add both properties. By altering to version check logic a little, you can accommodate upgrading from multiple versions pretty easily:&lt;/p&gt;

&lt;pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;padding-bottom:5px;background-color:#fbfbfb;min-height:40px;padding-left:5px;width:650px;padding-right:5px;overflow:auto;border-top:#cecece 1px solid;border-right:#cecece 1px solid;padding-top:5px;"&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (ComponentMetaData.Version &amp;lt; 1)
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;{
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;    &lt;span style="color:#008000;"&gt;//Perform upgrade for V1&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;}
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (ComponentMetaData.Version &amp;lt; 2)
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;{
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;    &lt;span style="color:#008000;"&gt;//Perform upgrade for V2&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;This change will ensure that the appropriate upgrade steps are taken for each version.&lt;/p&gt;

&lt;h3&gt;Some Other Thoughts&lt;/h3&gt;

&lt;p&gt;There’s a few things to be aware of with PerformUpgrade. One, it’s called only when the package is loaded, and the version stored in the package’s metadata is different than the binary component. This can occur both at design time (when the package is opened in Visual Studio), or at runtime (when executing the package from DTEXEC, etc).&lt;/p&gt;

&lt;p&gt;Two, when you update the CurrentVersion property, and then add the component to a new package, the version number in the package metadata will initially be set to 0. So the next time the package is opened, the PerformUpgrade will be performed. Since the ProvideComponentProperties would have already set the metadata appropriately for new version of the component, the PerformUpgrade can cause errors by attempting to add the same metadata again. This appears to be a bug in the behavior when adding the component to the data flow, and it occurs under both 2005 and 2008. The workaround is code the PerformUpgrade method to check before altering any metadata, to make sure that it doesn’t already exist.&lt;/p&gt;

&lt;p&gt;Three, due to what looks like another bug, when the package is opened the second time after the component is initially added to the package, the version will be incremented at the end of PerformUpgrade (assuming you use the code above that updates the version). However, this change does not mark the package as dirty in the designer, so the updated version number will not be saved unless some other property in the package is modified, and then the package is saved. This isn’t a huge problem – though you do need to make sure that the code in PerformUpgrade can be run repeatedly to avoid issues.&lt;/p&gt;

&lt;p&gt;That’s pretty much it. Hopefully this will be helpful if you are developing custom components for SSIS.&lt;/p&gt;&lt;img src="http://agilebi.com/cs/aggbug.aspx?PostID=357" width="1" height="1"&gt;</content><author><name>jwelch</name><uri>http://agilebi.com/cs/members/jwelch.aspx</uri></author><category term="SSIS" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/SSIS/default.aspx" /><category term="Components" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/Components/default.aspx" /><category term="Custom Tasks and Components" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/Custom+Tasks+and+Components/default.aspx" /></entry><entry><title>SSIS and SQL Azure – Getting Started</title><link rel="alternate" type="text/html" href="http://agilebi.com/cs/blogs/jwelch/archive/2009/08/25/ssis-and-sql-azure-getting-started.aspx" /><id>http://agilebi.com/cs/blogs/jwelch/archive/2009/08/25/ssis-and-sql-azure-getting-started.aspx</id><published>2009-08-25T21:44:25Z</published><updated>2009-08-25T21:44:25Z</updated><content type="html">&lt;p&gt;&lt;em&gt;Since SQL Azure is currently in a Community Technology Preview, the technology and this information provided below is subject to change. &lt;em&gt;This post is based on the August 18th CTP.&lt;/em&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Now that I’ve been working with SSIS against Azure for a few days, I thought I’d post about my experiences. Overall, I’m pretty happy with it, considering that it is a pre-release product. I’ve had some good and and some bad experiences, but with what I am seeing right now, and the direction it’s heading in, I think it has a good future.&lt;/p&gt;  &lt;p&gt;Prior to the CTP, people wanting to get an early start with SQL Azure were advised to developed locally against SQL Express. Theoretically, you could then simply change your connection strings to point to SQL Azure, and away you go. In practice, that’s not exactly how it worked for me with SSIS (your mileage may vary - .NET apps are probably much easier to port).&lt;/p&gt;  &lt;p&gt;Make sure you read through &lt;a href="http://msdn.microsoft.com/en-us/library/ee336279.aspx"&gt;the documentation&lt;/a&gt; first – there’s a lot of good information there, and some of it is pretty important. The first thing to note is that SQL Azure currently does not support OLE DB. The normal recommendation for SSIS is to use the OLE DB Source or Destination to access SQL Server. However, if you want to port your packages to SQL Azure, you must use the ADO.NET Source and Destinations. This is fine for 2008, but if you are using SSIS 2005, there is no ADO.NET Destination, so you would have to implement your own through a script component.&lt;/p&gt;  &lt;p&gt;The second thing to be aware of is that bulk insert operations are not currently supported (though it’s been said they will be available in a later CTP). Since the ADO.NET Destination doesn’t support bulk inserts anyway, this isn’t a huge issue. However, if you are writing your own destination (in a script component or custom component), you can’t currently use the ADO.NET SqlBulkCopy class.&lt;/p&gt;  &lt;p&gt;So, with those two caveats out of the way, it should be pretty much like creating any data flow in SSIS – add a source, add a destination, and you are ready to go. However, I got the following error when using the ADO.NET Source and Destination:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://agilebi.com/images/SSISandSQLAzureAugust18CTP_DE26/image.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://agilebi.com/images/SSISandSQLAzureAugust18CTP_DE26/image_thumb.png" width="727" height="211" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This error appears to come up because SQL Azure does not currently support the system catalog tables that ADO.NET calls to retrieve table information.&amp;#160; For the ADO.NET Source, since you can’t type the table name in, the simplest way to work around&amp;#160; this is to use the SQL Command option and specify a SQL Statement instead of the Table or View option. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://agilebi.com/images/SSISandSQLAzureAugust18CTP_DE26/image_3.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://agilebi.com/images/SSISandSQLAzureAugust18CTP_DE26/image_thumb_3.png" width="557" height="392" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;For the ADO.NET Destination, your only choice is to use the Table or View option, so you can just type the table name in. The table name must be provided in the following format: “schema”.”tablename”.&lt;/p&gt;  &lt;p&gt;Once this is done, you can run the package, and watch your data move. Once or twice, I saw validation warnings that prevented the package from running, but these all went away the next time I ran it, so I’m guessing it was a momentary connectivity issue. I’m on the road right now, so I don’t have the most stable internet connection available. &lt;/p&gt;  &lt;p&gt;I’ll be posting a follow up to this soon that talks about performance, and how you can tune your packages to move data in and out more quickly. I should also have a few performance test results to share.&lt;/p&gt;&lt;img src="http://agilebi.com/cs/aggbug.aspx?PostID=343" width="1" height="1"&gt;</content><author><name>jwelch</name><uri>http://agilebi.com/cs/members/jwelch.aspx</uri></author><category term="SSIS 2008" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/SSIS+2008/default.aspx" /><category term="SQL Azure" scheme="http://agilebi.com/cs/blogs/jwelch/archive/tags/SQL+Azure/default.aspx" /></entry></feed>