<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>A Developer&#039;s Blog &#187; data</title>
	<atom:link href="http://blog.hoegaerden.be/tag/data/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.hoegaerden.be</link>
	<description>SQL Server, BI, .NET, IT and anything else I have been playing with.</description>
	<lastBuildDate>Wed, 01 Feb 2012 16:15:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Hide/Show Items Dependant On Export Format (SSRS)</title>
		<link>http://blog.hoegaerden.be/2011/01/18/ssrs-hideshow-items-dependant-on-export-format/</link>
		<comments>http://blog.hoegaerden.be/2011/01/18/ssrs-hideshow-items-dependant-on-export-format/#comments</comments>
		<pubDate>Tue, 18 Jan 2011 18:00:02 +0000</pubDate>
		<dc:creator>Valentino Vranken</dc:creator>
				<category><![CDATA[Reporting Services]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[SQL Server 2008 R2]]></category>
		<category><![CDATA[SSRS]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://blog.hoegaerden.be/2011/01/18/ssrs-hideshow-items-dependant-on-export-format/</guid>
		<description><![CDATA[Now and then I encounter forum questions in the style of the following: I have a report with a title.  When rendered through the Report Manager and when exported to PDF, I want it to render as normal.  However, when exported to Excel I do not want to get the title.  How can I hide [...]]]></description>
			<content:encoded><![CDATA[<p>Now and then I encounter forum questions in the style of the following:</p>
<blockquote><p>I have a report with a title.  When rendered through the Report Manager and when exported to PDF, I want it to render as normal.  However, when exported to Excel I do not want to get the title.  How can I hide it?</p></blockquote>
<p>Because I don’t like re-inventing the wheel each time I decided to write a blog post about it.</p>
<p>As of SQL Server 2008 R2, we’ve got a built-in global field that can help us out.  This field is called <strong>Globals!RenderFormat</strong>.  It has two properties: <strong>Name</strong> and <strong>IsInteractive</strong>.  Name represents the unique name that indicates the chosen renderer, and IsInteractive indicates whether or not the chosen report format is, well, interactive.</p>
<p>Depending on the renderer, the values of the properties differ.  To be able to use the variable in an expression, we need to know its values for each rendering format.  Here’s the list of different possibilities:</p>
<table border="1" cellspacing="0" cellpadding="2" width="682">
<tbody>
<tr>
<td width="363" valign="top"><strong>Renderer</strong></td>
<td width="133" valign="top"><strong>RenderFormat.Name</strong></td>
<td width="184" valign="top"><strong>RenderFormat.IsInteractive</strong></td>
</tr>
<tr>
<td width="363" valign="top">Preview in BIDS or rendered through Report Manager</td>
<td width="133" valign="top">RPL</td>
<td width="184" valign="top">True</td>
</tr>
<tr>
<td width="363" valign="top">XML file with report data</td>
<td width="133" valign="top">XML</td>
<td width="184" valign="top">False</td>
</tr>
<tr>
<td width="363" valign="top">CSV (comma delimited)</td>
<td width="133" valign="top">CSV</td>
<td width="184" valign="top">False</td>
</tr>
<tr>
<td width="363" valign="top">TIFF file or Print button</td>
<td width="133" valign="top">IMAGE</td>
<td width="184" valign="top">False</td>
</tr>
<tr>
<td width="363" valign="top">PDF</td>
<td width="133" valign="top">PDF</td>
<td width="184" valign="top">False</td>
</tr>
<tr>
<td width="363" valign="top">MHTML (web archive)</td>
<td width="133" valign="top">MHTML</td>
<td width="184" valign="top">True</td>
</tr>
<tr>
<td width="363" valign="top">Excel</td>
<td width="133" valign="top">EXCEL</td>
<td width="184" valign="top">False</td>
</tr>
<tr>
<td width="363" valign="top">Word</td>
<td width="133" valign="top">WORD</td>
<td width="184" valign="top">False</td>
</tr>
</tbody>
</table>
<p>If these names for RenderFormat look familiar to you, you’re probably right.  Have a look at the <em>rsreportserver.config</em> file in the <em>C:\Program Files\Microsoft SQL Server\MSRS10_50.SQL2008R2\Reporting Services\ReportServer</em> folder.  Note that you may need to adapt the folder to your specific settings.  In my case my instance is called “SQL2008R2”.  Near the bottom of that configuration file you can find the <em>&lt;Render&gt; </em>node, located under <em>&lt;Extensions&gt;</em>.  The names that you see there are those used by the RenderFormat.Name property.</p>
<p>Now that we know what values to test on, let’s get started.</p>
<p>If we get back to the example of hiding a title, or textbox, when exporting to Excel, here’s what needs to happen.  Locate the <strong>Hidden</strong> property of the textbox that you want to hide, and give it the following expression:</p>
<pre class="code">=IIF(Globals!RenderFormat.Name = <span style="color: #a31515;">"EXCEL"</span>, <span style="color: blue;">True</span>, <span style="color: blue;">False</span>)</pre>
<p><a href="http://11011.net/software/vspaste"></a>What we’re saying here is: if the RenderFormat is EXCEL, then the Hidden property should be set to True.  Which results in a hidden textbox whenever the report is exported to Excel!</p>
<p><em>As Erik pointed out in the comments, in this particular case you don&#8217;t need the IIF() statement.  The result of the expression results in True when the expected value should be True, and False when False is expected.</em></p>
<p>As a quick note: when building your expression through the expression builder, you’ll notice that the Intellisense doesn’t know the new RenderFormat field yet.  Do not worry about that, just continue typing and ignore any errors being indicated.  If you use the syntax as I highlighted above, it will work!  Well, unless you’re running an earlier version than SQL Server 2008 R2 of course.  In that case it won’t work.</p>
<p><img style="display: inline; border: 0px;" title="Intellisense doesn't know RenderFormat yet" src="http://blog.hoegaerden.be/wp-content/uploads/image366.png" border="0" alt="Intellisense doesn't know RenderFormat yet" width="265" height="211" /></p>
<p>In contradiction to the Intellisense, the bottom part of the expression builder screen has been updated to show the new properties.  So if you don’t remember the syntax, you can just locate the field in the <em>Built-in Fields</em> category and give it a good double-click.</p>
<p><a href="http://blog.hoegaerden.be/wp-content/uploads/image367.png"><img style="display: inline; border: 0px;" title="RenderFormat is located in the Built-in Fields category" src="http://blog.hoegaerden.be/wp-content/uploads/image_thumb83.png" border="0" alt="RenderFormat is located in the Built-in Fields category" width="700" height="193" /></a></p>
<p>Of course, the Excel example in this post is just one of many possibilities that this new field offers.  Is your company environment-friendly and does it want to prevent wasting paper?  Now it’s possible, just hide that 50-pages long table when the report is being rendered for print!</p>
<p>Have fun!</p>
<p>Valentino.</p>
<p><strong>References</strong></p>
<p><a title="Globals!RenderFormat aka Renderer Dependent Report Layout" href="http://blogs.msdn.com/b/robertbruckner/archive/2010/05/02/globals-renderformat-aka-renderer-dependent-report-layout.aspx" target="_blank">Globals!RenderFormat aka Renderer Dependent Report Layout by Robert Bruckner</a></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.hoegaerden.be%2F2011%2F01%2F18%2Fssrs-hideshow-items-dependant-on-export-format%2F&amp;title=Hide%2FShow%20Items%20Dependant%20On%20Export%20Format%20%28SSRS%29" id="wpa2a_2"><img src="http://blog.hoegaerden.be/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.hoegaerden.be/2011/01/18/ssrs-hideshow-items-dependant-on-export-format/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>SQL Server Day 2010: The Videos</title>
		<link>http://blog.hoegaerden.be/2011/01/15/sql-server-day-2010-the-videos/</link>
		<comments>http://blog.hoegaerden.be/2011/01/15/sql-server-day-2010-the-videos/#comments</comments>
		<pubDate>Sat, 15 Jan 2011 14:27:04 +0000</pubDate>
		<dc:creator>Valentino Vranken</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Community Event]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[SQLUG]]></category>

		<guid isPermaLink="false">http://blog.hoegaerden.be/2011/01/15/sql-server-day-2010-the-videos/</guid>
		<description><![CDATA[Last month we had the pleasure of enjoying the third edition of our Belgian SQL Server Day.  If you were there and you were unable to attend a particular session, even though you were interested in it, here’s your answer.  The sessions have been recorded, and the videos are now available online!  How’s that for [...]]]></description>
			<content:encoded><![CDATA[<p>Last month we had the pleasure of enjoying the third edition of our Belgian SQL Server Day.  If you were there and you were unable to attend a particular session, even though you were interested in it, here’s your answer.  The sessions have been recorded, and the videos are now available online!  How’s that for a New Year’s present?</p>
<p><a title="SQL Server Day 2010: The Videos" href="http://www.sqlserverday.be/video/" target="_blank"><img style="display: inline; border: 0px;" title="SQL Server Day 2010: The Videos" src="http://blog.hoegaerden.be/wp-content/uploads/image365.png" border="0" alt="SQL Server Day 2010: The Videos" width="672" height="127" /></a></p>
<p>And if those videos didn’t still your hunger, or you just have plenty of time to kill, <a title="Chris Webb's BI Blog: Videos!" href="http://cwebbbi.wordpress.com/2011/01/12/powerpivot-videos-from-sql-server-day-2010/" target="_blank">check out this blog post on Chris Webb’s BI blog</a>.  He has posted a link to the 152 videos of SQL Bits, a three-day SQL Server event in the UK.</p>
<p>Still not satisfied?  Maybe these <a title="SQL Server 2008 Microsoft Certified Master (MCM) Readiness Videos" href="http://technet.microsoft.com/en-us/sqlserver/ff977043.aspx" target="_blank">SQL Server 2008 Microsoft Certified Master (MCM) Readiness Videos</a> can keep you busy for a little while then. <img src='http://blog.hoegaerden.be/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Have fun!</p>
<p>Valentino.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.hoegaerden.be%2F2011%2F01%2F15%2Fsql-server-day-2010-the-videos%2F&amp;title=SQL%20Server%20Day%202010%3A%20The%20Videos" id="wpa2a_4"><img src="http://blog.hoegaerden.be/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.hoegaerden.be/2011/01/15/sql-server-day-2010-the-videos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Where&#8217;s The (Windows) User?</title>
		<link>http://blog.hoegaerden.be/2011/01/14/wheres-the-windows-user/</link>
		<comments>http://blog.hoegaerden.be/2011/01/14/wheres-the-windows-user/#comments</comments>
		<pubDate>Fri, 14 Jan 2011 17:48:46 +0000</pubDate>
		<dc:creator>Valentino Vranken</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[T-SQL]]></category>

		<guid isPermaLink="false">http://blog.hoegaerden.be/2011/01/14/wheres-the-windows-user/</guid>
		<description><![CDATA[Have you ever needed to write a script that would store the Windows login of the user that executes the script in a table, without hard-coding it?  And you couldn’t find your way through the user jungle of T-SQL?  Then read on! A normal approach would be to rely on the IntelliSense feature of SSMS [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever needed to write a script that would store the Windows login of the user that executes the script in a table, without hard-coding it?  And you couldn’t find your way through the user jungle of T-SQL?  Then read on!</p>
<p>A normal approach would be to rely on the IntelliSense feature of SSMS and start typing something like:</p>
<pre class="code"><span style="color: blue;">select use</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Which gives you a dropdown like:</p>
<p><img style="display: inline; border-width: 0px;" title="image" src="http://blog.hoegaerden.be/wp-content/uploads/image363.png" border="0" alt="image" width="540" height="209" /></p>
<p>Cool you think, there are four system functions to return something user-related, one of them would be the Windows user, right?  Well, wrong.</p>
<p>Let’s find out what these functions actually return, and locate a method that does return what we require.</p>
<h2>The Different User-Related System Functions</h2>
<h3>USER</h3>
<p>According to the BOL:</p>
<blockquote><p>Allows a system-supplied value for the database user name of the current user to be inserted into a table when no default value is specified.</p></blockquote>
<p>So, how many times did you read that?  And do you now know what you’ll get?  Me neither.  As far as I understand it, you’ll get the database user name of the connection context.  Not what we need.</p>
<h3>USER_ID</h3>
<p>According to BOL:</p>
<blockquote><p>Returns the identification number for a database user.</p></blockquote>
<p>The function accepts one argument that accepts a string representing a username.  When no argument is provided, it will return the user ID of the execution context.</p>
<p>But that’s not important because the BOL also mentions that it will be removed in a future version and that you thus shouldn’t use it anymore.  No problem if you need it though, its replacement is called DATABASE_PRINCIPAL_ID.</p>
<h3>USER_NAME</h3>
<p>According to BOL:</p>
<blockquote><p>Returns a database user name from a specified identification number.</p></blockquote>
<p>This is the inverse of USER_ID.  It accepts one argument representing the user ID.  When omitted, the user of the current execution context will be returned.  Which is actually the equivalent of the USER function.</p>
<p>Still no Windows user though, so let’s move on to the next one.</p>
<h3>USER_SID</h3>
<p>Not documented in the BOL.</p>
<p>It seems to represent the <strong>sid </strong>column found through following query:</p>
<p><a href="http://11011.net/software/vspaste"></a></p>
<pre class="code"><span style="color: blue;">select </span><span style="color: gray;">* </span><span style="color: blue;">from </span><span style="color: green;">sys</span><span style="color: gray;">.</span><span style="color: green;">sysusers</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>And the sys.sysusers view is documented.  Apparently “sid” stands for “security identifier” and it’s a varbinary.  But not only is the view documented, it is also deprecated.  You should use the following view instead:</p>
<pre class="code"><span style="color: blue;">select </span><span style="color: gray;">* </span><span style="color: blue;">from </span><span style="color: green;">sys</span><span style="color: gray;">.</span><span style="color: green;">database_principals</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>That query returns a list of principals in the current database, and one of the fields is indeed our dear sid.  However, we can now conclude that sid is definitely not what we’re looking for in this little quest, it doesn’t even closely resemble a Windows user name.  So let’s move on again!</p>
<h3>CURRENT_USER</h3>
<p>Hmm, “current user”, will this finally be the Windows user with which I’m running my queries?</p>
<p>According to BOL:</p>
<blockquote><p>Returns the name of the current user. This function is equivalent to USER_NAME().</p></blockquote>
<p>Equivalent to USER_NAME, so still not what we’re looking for.</p>
<h3>SESSION_USER</h3>
<p>According to BOL:</p>
<blockquote><p>SESSION_USER returns the user name of the current context in the current database.</p></blockquote>
<p>You can probably guess by now that again this is not what we’re searching for.  Next.</p>
<h3>SYSTEM_USER</h3>
<p>According to BOL:</p>
<blockquote><p>Allows a system-supplied value for the current login to be inserted into a table when no default value is specified.</p></blockquote>
<p>Ah, finally a description that contains the word “login”!  And indeed, here’s what it returns:</p>
<blockquote><p>ORDINA\VaVr</p></blockquote>
<p>That is indeed my Windows user.  Mission accomplished!</p>
<p><strong><span style="text-decoration: underline;">Please note:</span></strong> if you’re running this through a window connected via a SQL Server login, you will get that login as opposed to your Windows login.  And if you get ‘sa’ while you’re connected to a production server you should look into making some security changes. <img src='http://blog.hoegaerden.be/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h3>SUSER_NAME and SUSER_SNAME</h3>
<p>Two more similar functions exist: SUSER_NAME and SUSER_SNAME.</p>
<p>Both return a login name as well, and both accept a parameter.  When executed without parameter, they return the login name of the current user.  Their only difference is the parameter that they accept.  SUSER_NAME accepts the “login identification number of the user”, which is an <strong>int</strong>, and SUSER_SNAME accepts the “login security identification number”, a <strong>varbinary(85)</strong> (remember sid from above?).</p>
<h3>Quick Query</h3>
<p>The following query shows how to use all the functions, with the default values for any parameters.</p>
<pre class="code"><span style="color: blue;">select </span><span style="color: magenta;">USER </span><span style="color: blue;">as </span>cUSER<span style="color: gray;">, </span><span style="color: magenta;">USER_ID</span><span style="color: gray;">() </span><span style="color: blue;">as </span>cUSER_ID<span style="color: gray;">, </span><span style="color: magenta;">USER_NAME</span><span style="color: gray;">() </span><span style="color: blue;">as </span><span style="color: magenta;">USER_NAME</span><span style="color: gray;">,
    </span><span style="color: magenta;">USER_SID</span><span style="color: gray;">() </span><span style="color: blue;">as </span>cUSER_SID<span style="color: gray;">, </span><span style="color: magenta;">CURRENT_USER </span><span style="color: blue;">as </span>cCURRENT_USER<span style="color: gray;">,
    </span><span style="color: magenta;">SESSION_USER </span><span style="color: blue;">as </span>cSESSION_USER<span style="color: gray;">, </span><span style="color: magenta;">SYSTEM_USER </span><span style="color: blue;">as </span>cSYSTEM_USER<span style="color: gray;">,
    </span><span style="color: magenta;">SUSER_NAME</span><span style="color: gray;">() </span><span style="color: blue;">as </span>cSUSER_NAME<span style="color: gray;">, </span><span style="color: magenta;">SUSER_SNAME</span><span style="color: gray;">() </span><span style="color: blue;">as </span>cSUSER_SNAME</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Have fun!</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.hoegaerden.be%2F2011%2F01%2F14%2Fwheres-the-windows-user%2F&amp;title=Where%26rsquo%3Bs%20The%20%28Windows%29%20User%3F" id="wpa2a_6"><img src="http://blog.hoegaerden.be/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.hoegaerden.be/2011/01/14/wheres-the-windows-user/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Server, What&#8217;s Your Version Number?</title>
		<link>http://blog.hoegaerden.be/2010/11/20/server-whats-your-version-number/</link>
		<comments>http://blog.hoegaerden.be/2010/11/20/server-whats-your-version-number/#comments</comments>
		<pubDate>Sat, 20 Nov 2010 19:32:27 +0000</pubDate>
		<dc:creator>Valentino Vranken</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[data]]></category>

		<guid isPermaLink="false">http://blog.hoegaerden.be/2010/11/20/server-whats-your-version-number/</guid>
		<description><![CDATA[Here’s a quick post about one of my favorite pages on the Microsoft Support site.&#160; The page explains how to retrieve your SQL Server version, and also mentions the different version numbers of all major releases and service packs. One of my favorite statements since many years is the following: select @@version; Here’s the output [...]]]></description>
			<content:encoded><![CDATA[<p>Here’s a quick post about one of my favorite pages on the <a title="Microsoft Support" href="http://support.microsoft.com/" target="_blank">Microsoft Support</a> site.&#160; The page explains how to retrieve your SQL Server version, and also mentions the different version numbers of all major releases and service packs.</p>
<p>One of my favorite statements since many years is the following:</p>
<pre class="code"><span style="color: blue">select </span><span style="color: magenta">@@version</span><span style="color: gray">;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Here’s the output that it produces on my laptop running Windows 7, while connected to my R2 server:</p>
<blockquote>
<p>Microsoft SQL Server 2008 R2 (RTM) &#8211; 10.50.1600.1 (X64)&#160;&#160; Apr&#160; 2 2010 15:48:46&#160;&#160; Copyright (c) Microsoft Corporation&#160; Enterprise Edition (64-bit) on Windows NT 6.1 &lt;X64&gt; (Build 7600: )</p>
</blockquote>
<p>It not only retrieves the version, edition and CPU architecture of SQL Server, on top of that it also shows you the operating system version on which it is running!</p>
<p>The statement is easy to remember and gives you all the details that you need.&#160; Well, that depends on the situation of course.&#160; In one of my previous jobs I was, as developer, last-line support for an application that was used worldwide.&#160; Which means that now and then I had people on the phone that had “some vague issue” with our application.&#160; And even though I speak four languages (more or less), I can assure you that getting details through a phone line can be a tough job.&#160; I remember one case where I had to spend half an hour to get the person on the other side find the Start button.&#160; Yes, that stupid thing on the bottom left, the thing that you need all the time as a regular Windows user.&#160; And no, they we’re not on Windows 3.x anymore!&#160; In those times, it even had the letters S T A R and T all over it!&#160; But alas, it remained impossible to find.&#160; Then I switched to finding the clock.&#160; Guess what: wasn’t in the right bottom corner either!&#160; Further during the conversation I tried all other corners, also tried to explain that the status bar may have been set to automatically hide.&#160; Oh well, at a certain point they’d suddenly found it!&#160; I don’t know where, maybe on another PC, at that point I didn’t care anymore, I just wanted them to open up the Management Studio, er, Query Analyzer more likely.</p>
<p>Anyway, at times like that, you’re glad that easy SQL commands still exist.</p>
<p>The statement above is not the only possibility to get details about the SQL Server version.&#160; Another method is through the SERVERPROPERTY function.&#160; Here’s a sample statement (from the Books Online) to retrieve version information:</p>
<pre class="code"><span style="color: blue">SELECT </span><span style="color: magenta">SERVERPROPERTY</span><span style="color: gray">(</span><span style="color: red">'ProductVersion'</span><span style="color: gray">) </span><span style="color: blue">AS </span>ProductVersion<span style="color: gray">,
    </span><span style="color: magenta">SERVERPROPERTY</span><span style="color: gray">(</span><span style="color: red">'ProductLevel'</span><span style="color: gray">) </span><span style="color: blue">AS </span>ProductLevel<span style="color: gray">,
    </span><span style="color: magenta">SERVERPROPERTY</span><span style="color: gray">(</span><span style="color: red">'Edition'</span><span style="color: gray">) </span><span style="color: blue">AS </span>Edition<span style="color: gray">,
    </span><span style="color: magenta">SERVERPROPERTY</span><span style="color: gray">(</span><span style="color: red">'EngineEdition'</span><span style="color: gray">) </span><span style="color: blue">AS </span>EngineEdition<span style="color: gray">;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Try getting that to the other side of the phone line!&#160; And no, email was not an option either…</p>
<p>Here’s the statement’s output:</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Output of SERVERPROPERTY sample statement" border="0" alt="Output of SERVERPROPERTY sample statement" src="http://blog.hoegaerden.be/wp-content/uploads/image357.png" width="422" height="67" /></p>
<p>Not only is the statement more difficult to remember, the output is less readable too.&#160; For instance you need to know that EngineEdition 3 means Enterprise Edition.</p>
<p>Nevertheless, it is a useful function with more possibilities than @@version.&#160; <a title="SERVERPROPERTY (Transact-SQL)" href="http://msdn.microsoft.com/en-us/library/ms174396.aspx" target="_blank">Check out the BOL</a> for all the details and available properties.</p>
<p>Let’s get back on topic now.&#160; I was going to mention a certain page on the Microsoft Support site.&#160; Here it is: <a title="Microsoft Support: How to identify your SQL Server version and edition" href="http://support.microsoft.com/kb/321185" target="_blank">How to identify your SQL Server version and edition</a>.</p>
<p>I think this page is a great reference in terms of versions.&#160; If someone wants to know what version of SQL Server he’s running and doesn’t know the version numbers, this is the place to be!&#160; I just whish that Microsoft would keep it more up-to-date.&#160; At this moment it’s not even mentioning SQL Server 2008 R2, while that was released about half a year ago.&#160; No sign of SP2 for SQL Server 2008 either.&#160; I’m going to provide feedback through the textbox at the bottom of the page with this exact statement.&#160; Hopefully that has some effect.</p>
<p>In case you are looking for those latest version numbers, here they are:</p>
<table border="0" cellspacing="0" cellpadding="2" width="400">
<tbody>
<tr>
<td valign="top" width="200"><strong>SQL Server 2008 SP2</strong></td>
<td valign="top" width="200">10.00.4000.00</td>
</tr>
<tr>
<td valign="top" width="200"><strong>SQL Server 2008 R2 RTM</strong></td>
<td valign="top" width="200">10.50.1600.1</td>
</tr>
</tbody>
</table>
<p>&#160;</p>
<p>Have fun!</p>
<p>Valentino.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.hoegaerden.be%2F2010%2F11%2F20%2Fserver-whats-your-version-number%2F&amp;title=Server%2C%20What%26rsquo%3Bs%20Your%20Version%20Number%3F" id="wpa2a_8"><img src="http://blog.hoegaerden.be/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.hoegaerden.be/2010/11/20/server-whats-your-version-number/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>First MCTS, Then MCITP</title>
		<link>http://blog.hoegaerden.be/2010/10/08/first-mcts-then-mcitp/</link>
		<comments>http://blog.hoegaerden.be/2010/10/08/first-mcts-then-mcitp/#comments</comments>
		<pubDate>Fri, 08 Oct 2010 18:37:47 +0000</pubDate>
		<dc:creator>Valentino Vranken</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Certification]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[MCITP]]></category>
		<category><![CDATA[MCP]]></category>
		<category><![CDATA[MCTS]]></category>

		<guid isPermaLink="false">http://blog.hoegaerden.be/2010/10/08/first-mcts-then-mcitp/</guid>
		<description><![CDATA[Not that long ago I posted an item showing off my third Microsoft Certified Technology Specialist (MCTS) certificate on SQL Server 2008.  With the MTCS certificates all in my pocket, the time had come to start on the Microsoft Certified IT Professional (MCITP) certification track. Yes, I’m happy to announce that I have passed the [...]]]></description>
			<content:encoded><![CDATA[<p>Not that long ago I posted an item showing off <a title="MCTS++" href="http://blog.hoegaerden.be/2010/07/11/mcts/">my third Microsoft Certified Technology Specialist (MCTS) certificate</a> on SQL Server 2008.  With the MTCS certificates all in my pocket, the time had come to start on the Microsoft Certified IT Professional (MCITP) certification track.</p>
<p><img style="display: inline; margin-left: 0px; margin-right: 0px; border: 0px;" title="Microsoft Certified IT Professional (MCITP), Database Developer 2008" src="http://blog.hoegaerden.be/wp-content/uploads/MCITPrgb_12551.png" border="0" alt="Microsoft Certified IT Professional (MCITP), Database Developer 2008" width="308" height="69" align="right" />Yes, I’m happy to announce that I have passed the 70-451 exam.  For those who are not familiar with the numbers, it’s the exam to get the MCITP Database Developer 2008 certificate.</p>
<p>Obviously I can’t say anything about the content of the exam, but what I can do is explain the questioning style with a fictitious example.</p>
<h2>Fictitious MCTS Question</h2>
<p>If you’ve done one of the MCTS exams, you know that there’s quite some focus on syntax stuff.  Here’s an example.</p>
<p><strong>Question Example</strong></p>
<p>Select the answer that completes the following sentence:</p>
<blockquote><p>Microsoft SQL Server 2008 is a …</p></blockquote>
<p>A. floppy drive system</p>
<p>B. Beta Ace Service</p>
<p>C. Database Server</p>
<p>D. Operating System</p>
<p><em>(Correct answer is C.)</em></p>
<p>Obviously this is fairly simple.  Now, imagine that the question mentions an incomplete query and you need to select the right answer to complete it.  And there are two (or more) similar answers that seem plausible to you.  Until you start thinking, sometimes thinking hard.  And then it hits you: three out of the four answers contain something to invalidate the query because of a syntax issue.</p>
<p>That’s the MCTS style.  I don’t really like it to be honest.  In real-life, when I’m not sure of the syntax, first of all the Management Studio will tell me .  If that’s not enough, I do a quick search in the Books Online and I’m good to go.  Obviously you won’t be able to answer these questions if you’re not familiar with the statements.  But then again, if you read about the syntax an hour before the exam, you’ll probably still remember it, and you will be able to answer the question.  What does that prove then?  I’ll leave the conclusion to you.  To be fair I need to mention that not all questions are like this.</p>
<h2>Fictitious MCITP Question</h2>
<p>The questioning style for the MCITP exam is a bit different.  There’s less focus on syntax details, or just one single detail, and more on the broader picture.  Again I’ll demonstrate with an example.</p>
<p><strong>Question Example<a title="Yearling T-bone steak" href="http://blog.hoegaerden.be/wp-content/uploads/image356.png" target="_blank"><img style="margin: 0px 0px 0px 5px; display: inline; border: 0px;" title="Yearling T-bone steak" src="http://blog.hoegaerden.be/wp-content/uploads/image_thumb82.png" border="0" alt="Yearling T-bone steak" width="219" height="212" align="right" /></a></strong></p>
<p>You’re hungry and you need to do something about it by method of eating.</p>
<p>What answer will solve your problem, taking into account that:</p>
<ul>
<li>you need to be able to do sports in an hour time</li>
<li>you don’t have a microwave oven</li>
<li>you’re allergic to certain types of fruit</li>
</ul>
<p>A. a T-Bone steak (500 grams) with a creamy pepper sauce accompanied by French Fries</p>
<p>B. cold pasta that you really don’t want to eat unheated</p>
<p>C. hot pasta with meat and zucchini</p>
<p>D. cold pasta with onion, apple and tomato</p>
<p><em>(Correct answer is C.)</em></p>
<p>Do you notice the difference?  You need a much broader knowledge to be able to solve these types of question.  For our example, you need to know that a microwave oven can be used to heat up food and you need to know that zucchini is not fruit.  Furthermore you need to be aware that answer A would be in conflict with the ability to do sports an hour after eating.</p>
<p>I prefer these types of question over the MCTS style.  I believe these require more knowledge of and on-the-job experience with the product.  And after all, proving that you have some knowledge about it is the whole point of the exams, right?</p>
<p>For another great story related to the 70-433 and 70-451 exams – that’s the MCTS and MCITP for the Database Developer 2008 credential – check out Brent Ozar’s blog post: <a title="MCM Prep Week: Microsoft Exams 70-433 and 70-451" href="http://www.brentozar.com/archive/2010/02/mcm-prep-week-microsoft-exam-70-433-and-70-451/" target="_blank">MCM Prep Week: Microsoft Exams 70-433 and 70-451</a>.  He wrote it while <a title="Brent Ozar on SQL MCM" href="http://www.brentozar.com/sql-mcm/" target="_blank">preparing for the MCM certification track</a>.</p>
<p>That’s it for now, have fun!</p>
<p>Valentino.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.hoegaerden.be%2F2010%2F10%2F08%2Ffirst-mcts-then-mcitp%2F&amp;title=First%20MCTS%2C%20Then%20MCITP" id="wpa2a_10"><img src="http://blog.hoegaerden.be/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.hoegaerden.be/2010/10/08/first-mcts-then-mcitp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL Server Day 2010</title>
		<link>http://blog.hoegaerden.be/2010/10/06/sql-server-day-2010/</link>
		<comments>http://blog.hoegaerden.be/2010/10/06/sql-server-day-2010/#comments</comments>
		<pubDate>Wed, 06 Oct 2010 19:52:48 +0000</pubDate>
		<dc:creator>Valentino Vranken</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[Community Event]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[SQLUG]]></category>

		<guid isPermaLink="false">http://blog.hoegaerden.be/2010/10/06/sql-server-day-2010/</guid>
		<description><![CDATA[For the third successive year the Belgian SQL Server User Group (SQLUG.BE vzw) and Microsoft are teaming up to organize the yearly Belgian SQL Server Day. After the successful event of last year, SQL Server Day 2010 will again be the biggest event focused exclusively on Microsoft SQL Server in Belgium and Luxembourg.  Join us [...]]]></description>
			<content:encoded><![CDATA[<p><a title="SQL Server Day 2010" href="http://www.sqlserverday.be/" target="_blank"><img style="display: inline; border: 0px;" title="SQL Server Day 2010" src="http://blog.hoegaerden.be/wp-content/uploads/image354.png" border="0" alt="SQL Server Day 2010" width="672" height="127" /></a></p>
<p>For the third successive year the <a href="http://www.sqlug.be/">Belgian SQL Server User Group</a> (SQLUG.BE vzw) and <a href="http://www.microsoft.be">Microsoft</a> are teaming up to organize the yearly Belgian SQL Server Day.</p>
<p>After the successful event of last year, SQL Server Day 2010 will again be the biggest event focused exclusively on Microsoft SQL Server in Belgium and Luxembourg.  Join us for sessions on SQL Azure, SQL Server 2008 R2, the Microsoft Business Intelligence platform and to connect with your peers.</p>
<p>This time the event will happen at <strong>San Marco Village in Schelle (Antwerp)</strong> and the date of the event is <strong>Thursday, December 2nd, 2010</strong>.  Book those calendars now!</p>
<p>Why would you want to be there?  Well, because there are going to be great speakers!  We’ve got some Belgian speakers and three (that’s right, 3) speakers from abroad!  Have you ever heard of <strong>Donald Farmer</strong>?  If you have, you’ll know that you want to be there.  If you have already seen him, you definitely know that you’ll want to be there.  And if you don’t know him: be there and you’ll see what I mean!</p>
<p>And he’s just one of a superb list.  The other speakers are<strong> Thomas Kejser, Chris Webb, Nico Jacobs, Wesley Backelant, Dirk Gubbels, Karel Coenye, Nico Verbaenen and Werner Geuens</strong>.</p>
<p>Furthermore, the full-day event will cost you zero euro.  So, what more do you want?  Free food??  Well, even that won’t be a problem!</p>
<p>One more thing: <a title="Register for SQL Server Day 2010" href="http://www.sqlserverday.be/register/" target="_blank">register now</a>!</p>
<p>And as usual, have fun!</p>
<p>Valentino.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.hoegaerden.be%2F2010%2F10%2F06%2Fsql-server-day-2010%2F&amp;title=SQL%20Server%20Day%202010" id="wpa2a_12"><img src="http://blog.hoegaerden.be/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.hoegaerden.be/2010/10/06/sql-server-day-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ask The Experts, Now!</title>
		<link>http://blog.hoegaerden.be/2010/09/01/ask-the-experts-now/</link>
		<comments>http://blog.hoegaerden.be/2010/09/01/ask-the-experts-now/#comments</comments>
		<pubDate>Wed, 01 Sep 2010 06:26:23 +0000</pubDate>
		<dc:creator>Valentino Vranken</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[Community Event]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[SQLUG]]></category>

		<guid isPermaLink="false">http://blog.hoegaerden.be/2010/09/01/ask-the-experts-now/</guid>
		<description><![CDATA[The Belgian SQL Server User Group is teaming up with Microsoft to organize an “Ask The Experts” event. The purpose of this event is to give you, the SQL Server user, an opportunity to ask Microsoft those things which you’ve always wanted to know but never could find on the internet. The questions are currently [...]]]></description>
			<content:encoded><![CDATA[<p>The Belgian SQL Server User Group is teaming up with Microsoft to organize an <strong>“Ask The Experts”</strong> event.</p>
<p>The purpose of this event is to give you, the SQL Server user, an opportunity to ask Microsoft those things which you’ve always wanted to know but never could find on the internet.</p>
<p>The questions are currently being gathered (that explains the “Now” in my post’s title).  This gives you some time to think about what you’d like to ask beforehand.  On the day of the event, these questions will then be answered by a panel of four SQL Server specialists.</p>
<p>So, ever wanted to ask Microsoft a question related to SQL Server?  Now’s the time to do it!  Send them to <a href="mailto:asktheexperts@sqlug.be">asktheexperts@sqlug.be</a>.</p>
<p><strong>Who’s The Panel?</strong></p>
<p>The panel consists of three Microsoft employees and one SQL Server MVP.  Here are the full details:</p>
<p><strong>&gt; Wesley Backelant &lt;</strong></p>
<p>In his role as a Technology Advisor at Microsoft, Wesley is responsible for helping customers understand the capabilities of SQL Server and the Microsoft Business Intelligence stack. Before joining Microsoft, Wesley was a Database Architect working on some of the largest implementations of SQL Server in Belgium. Wesley started his professional career in the SQL Server 6.5 timeframe and remained true to his passion ever since. Wesley is active on <a href="http://www.twitter.com/WesleyBackelant" target="_blank">Twitter</a> where he handles topics related to his favorite technology.</p>
<p><strong>&gt; Frederik Vandeputte &lt;</strong></p>
<p>Frederik Vandeputte is a Senior Consultant and partner at Kohera, the Microsoft SQL Server/Business Intelligence Competence Center of the Cronos Group. Frederik has been working with SQL Server since version 6.5. In his free time Frederik collects Microsoft certifications. His collection includes MCTS, MCSA, MCSE, MCDBA, MCITP, MCT, ranging from Windows 2000 and SQL Server 2000 up to SQL Server 2008. Frederik is one of the co-founders and the President of the Belgian SQL Server User Group (SQLUG.BE). In January 2008 Frederik, became the first Belgian MVP on SQL Server. Follow Frederik on his <a href="http://www.vandeputte.org/" target="_blank">website</a> and <a href="http://twitter.com/frederikvdp" target="_blank">twitter</a>.</p>
<p><strong>&gt; Dirk Gubbels &lt;</strong></p>
<p>Dirk Gubbels is a senior consultant at Microsoft, and has been working with SQL Server since version 4.2. As one of the few Microsoft Certified Database Architects he has been involved in the most demanding SQL server based applications in Belgium and all over the EMEA region. His main focus areas are Design, Performance and Availability for both OLTP and Business Intelligence environments.</p>
<p><strong>&gt; Gunther Beersaerts &lt;</strong></p>
<p>Gunther Beersaerts joined Microsoft in 1998 (on the launch day of SQL Server 7.0) as a Technical Marketer for MSDN/TechNet road shows and has held a number of technical roles during his career, including Systems Engineer, ATS, TSP roles covering a broad set of Microsoft Application Platform solutions. Over the past few years, Gunther has been active in technical roles for Databases and Business Intelligence platforms in EPG Belgium &amp; Luxemburg. He then became a Strategist in the CATM (Customer Advocacy and Technology Management) organization which is a key-connection between the Microsoft Development teams and Customers /Partners. In this role, Gunther focuses on the Microsoft Data Platform, including SQL Server and Business Intelligence solutions. Prior to Microsoft, he was a developer and messaging engineer at a large financial institution in Brussels.</p>
<p><strong>When?</strong></p>
<p>Wednesday, September 29th 2010, starting at 1900.</p>
<p><strong>Where?</strong></p>
<p>The Microsoft offices in Zaventem.</p>
<p>Don’t forget to <a title="SQLUG event: Ask the Experts - 29/09/2010" href="http://sqlug.be/nextevent/event/?id=24" target="_blank">register here</a>!</p>
<p>May the inspiration be with you while coming up with some questions <img src='http://blog.hoegaerden.be/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>See you there!</p>
<p>Valentino.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.hoegaerden.be%2F2010%2F09%2F01%2Fask-the-experts-now%2F&amp;title=Ask%20The%20Experts%2C%20Now%21" id="wpa2a_14"><img src="http://blog.hoegaerden.be/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.hoegaerden.be/2010/09/01/ask-the-experts-now/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>12 + 12 = 24</title>
		<link>http://blog.hoegaerden.be/2010/08/31/12-12-24/</link>
		<comments>http://blog.hoegaerden.be/2010/08/31/12-12-24/#comments</comments>
		<pubDate>Tue, 31 Aug 2010 07:36:17 +0000</pubDate>
		<dc:creator>Valentino Vranken</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[Community Event]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[PASS]]></category>

		<guid isPermaLink="false">http://blog.hoegaerden.be/2010/08/31/12-12-24/</guid>
		<description><![CDATA[For the second time this year, the SQL PASS folks are organizing another 24 Hours of PASS, a 24-hour free virtual training event.  Each session takes one hour, so there are 24 presentations in total.  Instead of putting them right after each other, this time they’ve decided to split the event in half: 12 hours [...]]]></description>
			<content:encoded><![CDATA[<p>For the <a title="This year's first 24 Hours of PASS" href="http://blog.hoegaerden.be/2010/04/28/another-24-hours-of-pass/" target="_blank">second time</a> this year, the SQL PASS folks are organizing another <strong>24 Hours of PASS</strong>, a 24-hour free virtual training event.  Each session takes one hour, so there are 24 presentations in total.  Instead of putting them right after each other, this time they’ve decided to split the event in half: 12 hours on the first day and another 12 hours on the second.</p>
<p><a href="http://www.sqlpass.org/24hours/fall2010/" target="_blank"><img style="display: inline; border: 0px;" title="image" src="http://blog.hoegaerden.be/wp-content/uploads/image351.png" border="0" alt="image" width="700" height="130" /></a></p>
<p><strong>When?</strong></p>
<p>Wednesday, September 15th and Thursday, September 16th.  Each day the sessions start at 1200 GMT, so for us Belgians we need to add two hours for our local time.</p>
<p>Is it an interesting idea to split the event in two?  During the day I have to work, so I usually enroll for some sessions during the evening, starting earliest at 1800 and ending around midnight.  Looking at the schedule for the Fall event, it means that I’ll be able to attend sessions during two evenings instead of one.  Except, Wednesday evening I go swimming with our oldest daughter.  Ah well, better luck next time.</p>
<p>So, what are you waiting for?  <a title="24 Hours of PASS - Fall 2010" href="http://www.sqlpass.org/24hours/fall2010/" target="_blank">Register here</a>, it’s free and it’s interesting!  (Well, it’s probably not interesting for everyone on this planet, but it should be interesting to you – otherwise you wouldn’t be reading my blog either <img src='http://blog.hoegaerden.be/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> )</p>
<p>If you require more info: <a title="24 Hours of PASS - Fall 2010: Schedule" href="http://www.sqlpass.org/24hours/fall2010/SessionsbySchedule.aspx" target="_blank">check out the agenda</a>!</p>
<p>Have fun!</p>
<p>Valentino.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.hoegaerden.be%2F2010%2F08%2F31%2F12-12-24%2F&amp;title=12%20%2B%2012%20%3D%2024" id="wpa2a_16"><img src="http://blog.hoegaerden.be/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.hoegaerden.be/2010/08/31/12-12-24/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Calculating LastXMonths Aggregations Using T-SQL and SSIS</title>
		<link>http://blog.hoegaerden.be/2010/08/26/calculating-lastxmonths-aggregations-using-t-sql-and-ssis/</link>
		<comments>http://blog.hoegaerden.be/2010/08/26/calculating-lastxmonths-aggregations-using-t-sql-and-ssis/#comments</comments>
		<pubDate>Thu, 26 Aug 2010 20:25:19 +0000</pubDate>
		<dc:creator>Valentino Vranken</dc:creator>
				<category><![CDATA[Integration Services]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[T-SQL]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[SSIS]]></category>

		<guid isPermaLink="false">http://blog.hoegaerden.be/2010/08/26/calculating-lastxmonths-aggregations-using-t-sql-and-ssis/</guid>
		<description><![CDATA[With the holidays I haven’t been able to write much.  So I’ll make up for it with this +3000 words article.  If you’re reading this early in the morning, you’d better get a double espresso first In this article I will demonstrate a method that can be used to calculate aggregations over a certain period [...]]]></description>
			<content:encoded><![CDATA[<p>With the holidays I haven’t been able to write much.  So I’ll make up for it with this +3000 words article.  If you’re reading this early in the morning, you’d better get a double espresso first <img src='http://blog.hoegaerden.be/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>In this article I will demonstrate a method that can be used to calculate aggregations over a certain period of time in the past, or LastXMonths aggregations as I’m calling them throughout the article.  I’ll be using T-SQL, SQL Server Integration Services and a relational database as source.  More specifically I will be using the Merge Join data transformation in SSIS, and Common Table Expressions in T-SQL.</p>
<p>Version-wise I’m using SQL Server 2008 R2, but this method should work as of SQL Server 2005.  Furthermore I’m using the Contoso DWH, <a title="Microsoft Contoso BI Demo Dataset for Retail Industry" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=868662DC-187A-4A85-B611-B7DF7DC909FC" target="_blank">available for download at the Microsoft Download Center</a>.  (In case you’re wondering, it’s the .BAK file.)</p>
<p>You can <a title="MergeJoin.dtsx" href="http://cid-81c8b064cbbe1698.office.live.com/self.aspx/.Public/blog/MergeJoin.dtsx" target="_blank">download the finished SSIS package from my Skydrive</a>.  (The file is called MergeJoin.dtsx.)</p>
<h2>The Scenario</h2>
<p>Let’s say we’ve got a relational database containing some sales figures.  Management has asked for sales-related data to be available somewhere for easy analysis.  Ideally a cube would be built for that purpose but as budgets are currently tight, a temporary solution needs to be provided meanwhile.  So it’s been decided that an additional table will be created, populated with the exact data as required by management.  This table should contain all details (number of items and amount of the sale) about products sold, grouped by the date of the sale, the zip code of the place where the sale occurred and the category of the product.</p>
<p>Furthermore, each record should contain the sum of all sales of the last month for the zip code and product category of each particular record.  Two additional aggregations should calculate the sales for the last three months and last six months.</p>
<h3>A Simple Example</h3>
<p>To make sure we’re all on the same track on the requirements, here’s a small example to illustrate the expected outcome.</p>
<p><a href="http://blog.hoegaerden.be/wp-content/uploads/image330.png"><img style="display: inline; border-width: 0px;" title="Small example displaying the expected outcome of the process" src="http://blog.hoegaerden.be/wp-content/uploads/image_thumb73.png" border="0" alt="Small example displaying the expected outcome of the process" width="676" height="79" /></a></p>
<p>I’ve omitted the SalesAmount numbers for readability reasons.  The records are ordered chronologically, with the oldest first.  As you can see, the bottom record shows 16 as value for Last6MSalesQuantity.  This is the result of the SalesQuantity of the current record and the SalesQuantity of the previous record, which happens to fall within the timespan of the lowest record’s SaleDate going back six months.  The two other records do not fall within the six months timespan and are thus not included in the sum for the Last6MSalesQuantity of that bottom record.</p>
<h2>Fetching The Data Into A Table</h2>
<p>Our scenario requires that the sales figures are calculated and put into a new table.  Let’s first start with creating the queries to fetch the data.</p>
<h3>Step 1: The Daily Numbers</h3>
<p>The easiest part are the daily sales numbers.  These can be retrieved fairly easy from the Contoso data warehouse, just by using a GROUP BY clause as shown in the following query.</p>
<p><a href="http://11011.net/software/vspaste"></a></p>
<pre class="code"><span style="color: green;">--daily sales
</span><span style="color: blue;">select </span>DD<span style="color: gray;">.</span>Datekey<span style="color: gray;">, </span>DS<span style="color: gray;">.</span>ZipCode<span style="color: gray;">, </span>DPC<span style="color: gray;">.</span>ProductCategoryName<span style="color: gray;">,
    </span><span style="color: magenta;">SUM</span><span style="color: gray;">(</span>FS<span style="color: gray;">.</span>SalesAmount<span style="color: gray;">) </span>SalesAmount_SUM<span style="color: gray;">,
    </span><span style="color: magenta;">SUM</span><span style="color: gray;">(</span>FS<span style="color: gray;">.</span>SalesQuantity<span style="color: gray;">) </span>SalesQuantity_SUM
<span style="color: blue;">from </span>dbo<span style="color: gray;">.</span>FactSales FS
    <span style="color: gray;">inner join </span>dbo<span style="color: gray;">.</span>DimStore DS <span style="color: blue;">on </span>DS<span style="color: gray;">.</span>StoreKey <span style="color: gray;">= </span>FS<span style="color: gray;">.</span>StoreKey
    <span style="color: gray;">inner join </span>dbo<span style="color: gray;">.</span>DimProduct DP <span style="color: blue;">on </span>DP<span style="color: gray;">.</span>ProductKey <span style="color: gray;">= </span>FS<span style="color: gray;">.</span>ProductKey
    <span style="color: gray;">inner join </span>dbo<span style="color: gray;">.</span>DimProductSubcategory DPS
        <span style="color: blue;">on </span>DPS<span style="color: gray;">.</span>ProductSubcategoryKey <span style="color: gray;">= </span>DP<span style="color: gray;">.</span>ProductSubcategoryKey
    <span style="color: gray;">inner join </span>dbo<span style="color: gray;">.</span>DimProductCategory DPC
        <span style="color: blue;">on </span>DPC<span style="color: gray;">.</span>ProductCategoryKey <span style="color: gray;">= </span>DPS<span style="color: gray;">.</span>ProductSubcategoryKey
    <span style="color: gray;">inner join </span>dbo<span style="color: gray;">.</span>DimDate DD <span style="color: blue;">on </span>DD<span style="color: gray;">.</span>Datekey <span style="color: gray;">= </span>FS<span style="color: gray;">.</span>DateKey
<span style="color: blue;">group by </span>DD<span style="color: gray;">.</span>Datekey<span style="color: gray;">, </span>DS<span style="color: gray;">.</span>ZipCode<span style="color: gray;">, </span>DPC<span style="color: gray;">.</span>ProductCategoryName
<span style="color: blue;">order by </span>DD<span style="color: gray;">.</span>Datekey <span style="color: blue;">asc</span><span style="color: gray;">, </span>DS<span style="color: gray;">.</span>ZipCode <span style="color: blue;">asc</span><span style="color: gray;">, </span>DPC<span style="color: gray;">.</span>ProductCategoryName <span style="color: blue;">asc</span><span style="color: gray;">;
</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Part of the result of that query looks like this:</p>
<p><img style="display: inline; border-width: 0px;" title="Result of the daily sales query" src="http://blog.hoegaerden.be/wp-content/uploads/image331.png" border="0" alt="Result of the daily sales query" width="610" height="218" /></p>
<p>Nothing special to mention so far so let’s continue to the next step.</p>
<h3>Step 2: The Monthly Numbers</h3>
<p>In this step, we’ll use the query from step 1 as base for the full query.  I’ll first show you the query and then provide you with some explanation of what’s going on.</p>
<pre class="code"><span style="color: green;">--LastMonth
</span><span style="color: blue;">declare </span>@numberOfMonths <span style="color: blue;">tinyint </span><span style="color: gray;">= </span>1<span style="color: gray;">;
</span><span style="color: blue;">with </span>DailySalesData <span style="color: blue;">as
</span><span style="color: gray;">(
    </span><span style="color: blue;">select </span>DD<span style="color: gray;">.</span>Datekey<span style="color: gray;">, </span>DS<span style="color: gray;">.</span>ZipCode<span style="color: gray;">, </span>DPC<span style="color: gray;">.</span>ProductCategoryName<span style="color: gray;">,
        </span><span style="color: magenta;">SUM</span><span style="color: gray;">(</span>FS<span style="color: gray;">.</span>SalesAmount<span style="color: gray;">) </span>SalesAmount_SUM<span style="color: gray;">,
        </span><span style="color: magenta;">SUM</span><span style="color: gray;">(</span>FS<span style="color: gray;">.</span>SalesQuantity<span style="color: gray;">) </span>SalesQuantity_SUM
    <span style="color: blue;">from </span>dbo<span style="color: gray;">.</span>FactSales FS
        <span style="color: gray;">inner join </span>dbo<span style="color: gray;">.</span>DimStore DS <span style="color: blue;">on </span>DS<span style="color: gray;">.</span>StoreKey <span style="color: gray;">= </span>FS<span style="color: gray;">.</span>StoreKey
        <span style="color: gray;">inner join </span>dbo<span style="color: gray;">.</span>DimProduct DP <span style="color: blue;">on </span>DP<span style="color: gray;">.</span>ProductKey <span style="color: gray;">= </span>FS<span style="color: gray;">.</span>ProductKey
        <span style="color: gray;">inner join </span>dbo<span style="color: gray;">.</span>DimProductSubcategory DPS
            <span style="color: blue;">on </span>DPS<span style="color: gray;">.</span>ProductSubcategoryKey <span style="color: gray;">= </span>DP<span style="color: gray;">.</span>ProductSubcategoryKey
        <span style="color: gray;">inner join </span>dbo<span style="color: gray;">.</span>DimProductCategory DPC
            <span style="color: blue;">on </span>DPC<span style="color: gray;">.</span>ProductCategoryKey <span style="color: gray;">= </span>DPS<span style="color: gray;">.</span>ProductSubcategoryKey
        <span style="color: gray;">inner join </span>dbo<span style="color: gray;">.</span>DimDate DD <span style="color: blue;">on </span>DD<span style="color: gray;">.</span>Datekey <span style="color: gray;">= </span>FS<span style="color: gray;">.</span>DateKey
    <span style="color: blue;">group by </span>DD<span style="color: gray;">.</span>Datekey<span style="color: gray;">, </span>DS<span style="color: gray;">.</span>ZipCode<span style="color: gray;">, </span>DPC<span style="color: gray;">.</span>ProductCategoryName
<span style="color: gray;">),
</span>UniqueRecordsPerDay <span style="color: blue;">as
</span><span style="color: gray;">(
    </span><span style="color: blue;">select </span>Datekey<span style="color: gray;">, </span>ZipCode<span style="color: gray;">, </span>ProductCategoryName
    <span style="color: blue;">from </span>DailySalesData
    <span style="color: blue;">group by </span>Datekey<span style="color: gray;">, </span>ZipCode<span style="color: gray;">, </span>ProductCategoryName
<span style="color: gray;">)
</span><span style="color: blue;">select </span>UR<span style="color: gray;">.</span>Datekey<span style="color: gray;">, </span>DSD<span style="color: gray;">.</span>ZipCode<span style="color: gray;">, </span>DSD<span style="color: gray;">.</span>ProductCategoryName<span style="color: gray;">,
    </span><span style="color: magenta;">SUM</span><span style="color: gray;">(</span>DSD<span style="color: gray;">.</span>SalesAmount_SUM<span style="color: gray;">) </span>SalesAmount_SUM<span style="color: gray;">,
    </span><span style="color: magenta;">SUM</span><span style="color: gray;">(</span>DSD<span style="color: gray;">.</span>SalesQuantity_SUM<span style="color: gray;">) </span>SalesQuantity_SUM
<span style="color: blue;">from </span>DailySalesData DSD
    <span style="color: gray;">inner join </span>UniqueRecordsPerDay UR
            <span style="color: blue;">on </span>UR<span style="color: gray;">.</span>ProductCategoryName <span style="color: gray;">= </span>DSD<span style="color: gray;">.</span>ProductCategoryName
        <span style="color: gray;">and </span>UR<span style="color: gray;">.</span>ZipCode <span style="color: gray;">= </span>DSD<span style="color: gray;">.</span>ZipCode
        <span style="color: gray;">and </span>DSD<span style="color: gray;">.</span>Datekey
            <span style="color: gray;">between </span><span style="color: magenta;">DATEADD</span><span style="color: gray;">(</span><span style="color: magenta;">month</span><span style="color: gray;">, -</span>@numberOfMonths<span style="color: gray;">, </span>UR<span style="color: gray;">.</span>Datekey <span style="color: gray;">+ </span>1<span style="color: gray;">)
            and </span>UR<span style="color: gray;">.</span>Datekey
<span style="color: blue;">group by </span>UR<span style="color: gray;">.</span>Datekey<span style="color: gray;">, </span>DSD<span style="color: gray;">.</span>ZipCode<span style="color: gray;">, </span>DSD<span style="color: gray;">.</span>ProductCategoryName
<span style="color: blue;">order by </span>UR<span style="color: gray;">.</span>Datekey <span style="color: blue;">asc</span><span style="color: gray;">, </span>DSD<span style="color: gray;">.</span>ZipCode <span style="color: blue;">asc</span><span style="color: gray;">, </span>DSD<span style="color: gray;">.</span>ProductCategoryName <span style="color: blue;">asc</span><span style="color: gray;">;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>The query uses a variable called @numberOfMonths.  This will allow us to use the same query for the totals of last month, as well as for the Last3M and the Last6M numbers.  All that’s needed is changing the variable to 3 or 6.</p>
<p>But how does the query get to the results?  To start, it uses two CTEs (Common Table Expressions).  The first one is called DailySalesData.  And the query for that CTE should look familiar to you by now: it’s the one from step 1, without the ORDER BY clause.</p>
<p>The second CTE is called UniqueRecordsPerDay and gives us one record for each unique date, zip code and product category as found in the Contoso data.  The DateKey, ZipCode and ProductCategoryName fields are our key grouping fields.  And this CTE is actually the key to calculating the monthly aggregated data, as I’ll explain next.</p>
<p>What the main query does is the following.  It selects the data from the DailySalesData CTE and joins that with the unique records per day recordset.  All grouping key fields need to be included in the join.  However, as you can see, to add the DateKey into the join I’m not just using the equals operator but the BETWEEN keyword instead.  I’ve also used the DATEADD function to subtract the number of months as specified through the @numberOfMonths variable.  That statement is saying: “give me all records starting from DateKey, going back @numberOfMonths”.  The query again groups by the key fields to be able to sum the records up.</p>
<p>This construction ensures that the SalesAmount_SUM and SalesQuantity_SUM fields represent the sum for the record’s zip code and product category and for the period as indicated by the @numberOfMonths variable.</p>
<h3>Step 3: Merging It All Together Into One Table</h3>
<p>Now that we know how to retrieve the data, we still need to get it into a table.  One option would be to use the INSERT statement on the daily records, followed by UPDATE statements to populate the monthly (1, 3, 6) aggregated columns.  However, I’m a BI guy so let’s use an SSIS package to get to the result (plus it allows me to illustrate the Merge Join data flow transformation <img src='http://blog.hoegaerden.be/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> ).</p>
<p>So open up the BIDS and create a new package.  Drop a Data Flow Task into the Control Flow and add a Connection Manager connecting to your Contoso DWH.  Then switch to the Data Flow page.</p>
<p>Nothing special so far I believe.  Next we need to set up four Data Flow Sources: one for the daily figures, one for the monthly, one for the 3M and one for the 6M data.</p>
<h4>Setting Up The Data Sources</h4>
<p>Throw in an OLE DB Source component, configure it to use your connection manager and copy/paste the first query above into the command textbox.  Again nothing special, right?</p>
<p>However, the Merge Join component expects its incoming data to be sorted.  That’s why I’ve included the ORDER BY clause in the queries above.  But that’s not all.  Connecting our data source to a Merge Join transformation without any additional change will result in an error such as the following:</p>
<blockquote><p>Validation error. Data Flow Task Merge Join [457]: The input is not sorted. The &#8220;input &#8220;Merge Join Left Input&#8221; (458)&#8221; must be sorted.</p></blockquote>
<p>To avoid this error, we need to explicitly inform our data flow that the data is actually ordered, and we need to give it all the details: on what fields has the data been ordered and in what order!  And that needs to be done through the Advanced Editor.</p>
<p>So, right-click the OLE DB Source and select <em>Show Advanced Editor</em>.</p>
<p><img style="display: inline; border-width: 0px;" title="Right-click OLE DB Source to open up the Advanced Editor" src="http://blog.hoegaerden.be/wp-content/uploads/image332.png" border="0" alt="Right-click OLE DB Source to open up the Advanced Editor" width="374" height="415" /></p>
<p>In the <strong>Advanced Editor</strong>, navigate to the last tab called <em>Input and Output Properties</em> and select the “OLE DB Source Output” node in the tree structure on the left.  Doing that will show the properties for the selected output and one of those properties is called <strong>IsSorted</strong>.  By default it is set to False.  Set it to True.</p>
<p><span style="text-decoration: underline;"><strong>Tip:</strong></span> double-clicking the label of the property will swap its value to the other value.  This can be useful in cases when you need to change several options but even here is saves a couple of clicks.  It’s all about optimization. <img src='http://blog.hoegaerden.be/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><a href="http://blog.hoegaerden.be/wp-content/uploads/image333.png"><img style="display: inline; border-width: 0px;" title="Advanced Editor on OLE DB Source: the IsSorted property" src="http://blog.hoegaerden.be/wp-content/uploads/image_thumb74.png" border="0" alt="Advanced Editor on OLE DB Source: the IsSorted property" width="700" height="632" /></a></p>
<p>At this moment the component knows that the incoming data is sorted, but it still doesn’t know on what fields.  To specify that, open up the OLE DB Source Output node, followed by the Output Columns node.  You’ll now see the list of fields.  As specified in the query, the data is ordered firstly on DateKey, secondly on ZipCode and thirdly on ProductCategoryName.</p>
<p>Select DateKey to see its properties.</p>
<p><a href="http://blog.hoegaerden.be/wp-content/uploads/image334.png"><img style="display: inline; border-width: 0px;" title="Advanced Editor of OLE DB Source showing the SortKeyPosition property" src="http://blog.hoegaerden.be/wp-content/uploads/image_thumb75.png" border="0" alt="Advanced Editor of OLE DB Source showing the SortKeyPosition property" width="700" height="678" /></a></p>
<p>The property in which we’re interested here is called <strong>SortKeyPosition</strong>.  By default it is set to zero.  When the incoming data is sorted,  this property should reflect in what order the data is sorted, starting with one for the first field.  So in our case here the value should be set to 1.</p>
<p>Set the SortKeyPosition property for ZipCode to 2 and for ProductCategoryName to 3.</p>
<p>That’s one of the four OLE DB sources set up.  The other three will be easier as we can start from the first one.  So, copy and paste the source component, open it up by double-clicking it and replace the query with our second query from earlier, the one returning the monthly figures.  Ow, and give it a decent name but I’m sure you knew that.</p>
<p>Create the third source component in the same way, but change the value for the @numberOfMonths variable to 3.  And again the same process for source number four, changing the variable’s value to 6.</p>
<p>Here’s what we have so far:</p>
<p><img style="display: inline; border-width: 0px;" title="Four OLE DB sources set up - waiting to be merged" src="http://blog.hoegaerden.be/wp-content/uploads/image335.png" border="0" alt="Four OLE DB sources set up - waiting to be merged" width="635" height="61" /></p>
<h4>Merging The Sources Into One Flow</h4>
<p>Next up is merging the incoming flows.  Drag a<strong> Merge Join </strong>data flow transformation under the Daily Sales source and connect the source to the Merge Join.  That will open the following <strong>Input Output Selection </strong>screen.</p>
<p><img style="display: inline; border-width: 0px;" title="Input Output Selection window" src="http://blog.hoegaerden.be/wp-content/uploads/image336.png" border="0" alt="Input Output Selection window" width="560" height="303" /></p>
<p>A Merge Join expects two inputs: one is called the <em>Left Input</em> and the other is called the <em>Right Input</em>.  Select <em>Merge Join Left Input </em>as value for the <strong>Input </strong>dropdown.</p>
<p>Close the popup window and connect the second source (with the monthly data) as well to the Merge Join.  There’s only one input remaining so this one is automatically the right input – no popup window is shown.</p>
<p>Next we need to configure the Merge Join so that it merges the data as expected.  Open the <strong>Merge Join Transformation Editor</strong> by double-clicking the component.</p>
<p><a href="http://blog.hoegaerden.be/wp-content/uploads/image337.png"><img style="display: inline; border-width: 0px;" title="Merge Join Transformation Editor" src="http://blog.hoegaerden.be/wp-content/uploads/image_thumb76.png" border="0" alt="Merge Join Transformation Editor" width="700" height="659" /></a></p>
<p>By default the <strong>Join type</strong> dropdown is set to <em>Inner join</em>.  In our situation that’s good enough.  In the case that only one record exists for a certain zip code and product category on a given day, the monthly data for this record will be the sum of just that one record but in any case: there’s always at least one record for each incoming flow to be combined with each other.</p>
<p>As you can see, because both incoming flows are ordered in the same way, it automatically knows on which fields to put the join.</p>
<p>By default, no output fields are created as the white bottom half of the screenshot indicates.</p>
<p>Now I’ll show you a screenshot of the expected setup:</p>
<p><img style="display: inline; border-width: 0px;" title="Merge Join Transformation Editor set up as expected" src="http://blog.hoegaerden.be/wp-content/uploads/image338.png" border="0" alt="Merge Join Transformation Editor set up as expected" width="700" height="659" /></p>
<p>There are several ways to specify the output fields.  The first method is by using the dropdown in the <strong>Input</strong> column.  Selecting a value there will populate a dropdown in the column called <strong>Input Column</strong> (djeez, that was one column too much).  Here’s what that method looks like:</p>
<p><img style="display: inline; border-width: 0px;" title="Specifying the output fields by using the dropdowns" src="http://blog.hoegaerden.be/wp-content/uploads/image339.png" border="0" alt="Specifying the output fields by using the dropdowns" width="340" height="106" /></p>
<p>Selecting a value in the second column will then give you a default value for the <strong>Output Alias</strong>.  This default can be freely modified.  As you may have guessed, this is not my preferred method – way too many comboboxes.</p>
<p>Another method of specifying the output fields is by using the checkboxes in front of the fields in the top part of the window.  I believe the larger screenshot above says it all.  Just check the fields that you need and then change their default Output Alias to whatever suits you.   In my example here I only needed to modify the alias for the last two records.</p>
<p>With our first Merge Join set up, only two are remaining.  So drag in a second Merge Join from the Toolbox, connect the output of the first join as Left Input on the second join and add the output of the third OLE DB source as Right Input.</p>
<p>Interesting to note here is that the output of the Merge Join is sorted in the same manner as its inputs.  One way of verifying this is by right-clicking the connector between the two joins and choosing <em>Edit</em>.</p>
<p><img style="display: inline; border-width: 0px;" title="Right-click data flow connector and select Edit to open up Data Flow Path Editor" src="http://blog.hoegaerden.be/wp-content/uploads/image340.png" border="0" alt="Right-click data flow connector and select Edit to open up Data Flow Path Editor" width="415" height="360" /></p>
<p>That opens up the <strong>Data Flow Path Editor</strong>.</p>
<p><strong><span style="text-decoration: underline;">Tip:</span></strong> double-clicking the connector will also open the editor!</p>
<p><a href="http://blog.hoegaerden.be/wp-content/uploads/image341.png"><img style="display: inline; border-width: 0px;" title="Examine the Metadata of the Data Flow Path to verify the sort order" src="http://blog.hoegaerden.be/wp-content/uploads/image_thumb77.png" border="0" alt="Examine the Metadata of the Data Flow Path to verify the sort order" width="700" height="472" /></a></p>
<p>As you can see in the above screenshot, the metadata page shows a list of the available fields with some properties, such as the Sort Key Position.  Now if that doesn’t look familiar?! <img src='http://blog.hoegaerden.be/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>So far, the second Merge Join has been added and connected but it hasn’t been configured yet.  The process is very similar to the way we’ve set up the first join.  Just select all fields from the left input by checking all the checkboxes and select the two SUM fields from the right input.  Don’t forget to give those SUM fields a clear name.</p>
<p>Two joins done, one remaining.  Just drag one in and connect it with the second join plus the last remaining OLE DB source.  I won’t go into further details here, it’s exactly the same as I just explained for the second join.</p>
<p>Here’s what the Data Flow should look like:</p>
<p><img style="display: inline; border-width: 0px;" title="The Data Flow with all the Merge Joins connected" src="http://blog.hoegaerden.be/wp-content/uploads/image342.png" border="0" alt="The Data Flow with all the Merge Joins connected" width="628" height="295" /></p>
<p>And here’s what the third Merge Join should look like:<a href="http://blog.hoegaerden.be/wp-content/uploads/image343.png"><img style="display: inline; border-width: 0px;" title="The third Merge Join as set up for the example" src="http://blog.hoegaerden.be/wp-content/uploads/image_thumb78.png" border="0" alt="The third Merge Join as set up for the example" width="700" height="703" /></a></p>
<h4>An Error That You May Encounter</h4>
<p>When using sorted data flows and the Merge Join component, you may encounter the following error message:</p>
<p><img style="display: inline; border-width: 0px;" title="An error that you may encounter while using the Merge Join component" src="http://blog.hoegaerden.be/wp-content/uploads/image344.png" border="0" alt="An error that you may encounter while using the Merge Join component" width="700" height="219" /></p>
<p>And now in words for the search engines:</p>
<blockquote><p>The component has detected potential metadata corruption during validation.</p>
<p>Error at Data Flow Task [SSIS.Pipeline]: The IsSorted property of output “Merge Join Output” (91) is set to TRUE, but the absolute values of the non-zero output column SortKeyPositions do not form a monotonically increasing sequence, starting at one.</p></blockquote>
<p>Yeah right, you had to read that twice, didn’t you?  And the best is yet to come:</p>
<blockquote><p>Due to limitations of the Advanced Editor dialog box, this component cannot be edited using this dialog box.</p></blockquote>
<p>So there’s a problem with your Merge Join but you cannot use the Advanced Editor to fix it, hmm, and you call that the ADVANCED editor?  Is there anything more advanced perhaps?  Well, actually, there is.  It’s called the Properties pane.  With the Merge Join selected, one of the properties there is called <strong>NumKeyColumns</strong>.  That property reflects on how many columns the incoming data is sorted.  And currently it contains the wrong value.  Changing its value to the correct number of columns will remove the error.</p>
<p><img style="display: inline; border-width: 0px;" title="Properties pane displaying the Merge Join's properties, including NumKeyColumns" src="http://blog.hoegaerden.be/wp-content/uploads/image345.png" border="0" alt="Properties pane displaying the Merge Join's properties, including NumKeyColumns" width="311" height="368" /></p>
<p>In case you’re wondering when you might encounter this particular problem, here’s how you can simulate it.  (Don’t forget to make a copy of the package before messing around with it.)</p>
<p>With the package as it currently is, remove the ZipCode field from the first two sources by unchecking it in the Columns page of the OLE DB Source Editor.</p>
<p>The sources are now complaining so open up their Advanced Editor and correct the SortKeyPosition of the ProductCategoryName field: it should become 2 instead of 3 because ZipCode was 2 and has been removed.</p>
<p>Now try to open the first Merge Join.  The first time it will complain about invalid references so delete those.  With the references deleted, if you now try to open the Merge Join editor, you’ll see the error we’re discussing here.  To fix it, change the NumKeyColumns property of the Merge Join to 2 instead of 3.</p>
<h4>Adding The Destination Table</h4>
<p>Now there’s only one step remaining: adding a destination for our merged data.  So, throw in an <strong>OLE DB Destination </strong>and connect it with the output of the last Merge Join:</p>
<p><img style="display: inline; border-width: 0px;" title="An OLE DB Destination connected to the join that merges it all together" src="http://blog.hoegaerden.be/wp-content/uploads/image346.png" border="0" alt="An OLE DB Destination connected to the join that merges it all together" width="153" height="171" /></p>
<p>I’ll just use a quick and dirty way of creating a new table in the database.  Open up the OLE DB Destination Editor by double-clicking it and select a Connection Manager in the dropdown.  Now click the <strong>New</strong> button next to the <em>Name of the table or the view</em> dropdown.</p>
<p>That opens up the Create Table window, with a CREATE TABLE query pre-generated for you for free.  Isn’t that nice?  Change the name of the table to something nice (at least remove those spaces, yuk!!) and click OK.</p>
<p><img style="display: inline; border-width: 0px;" title="The Create Table window" src="http://blog.hoegaerden.be/wp-content/uploads/image347.png" border="0" alt="The Create Table window" width="512" height="446" /></p>
<p>The new table is created at the moment that the OK button gets clicked.</p>
<p>Right, so are we there?  Well, almost.  As you can see now in the next screenshot, the BIDS does not want us to click the OK button just yet.</p>
<p><a href="http://blog.hoegaerden.be/wp-content/uploads/image348.png"><img style="display: inline; border-width: 0px;" title="The OLE DB Destination Editor with the Mappings still missing" src="http://blog.hoegaerden.be/wp-content/uploads/image_thumb79.png" border="0" alt="The OLE DB Destination Editor with the Mappings still missing" width="700" height="654" /></a></p>
<p>To resolve that warning, just open the Mappings page.  As the names of the input columns are matching exactly with the names of the fields in the destination table, everything will be automagically configured at this moment.  So now you can close the window with the OK button.</p>
<p>And that’s it!  Everything is set up to populate the new table with the aggregated figures, as requested by management.  To give it a run, right-click your package in the Solution Explorer and guess what… select Execute Package!  If everything has been configured as expected, you should get some green boxes soon.  And some data in the table, like this:</p>
<p><a href="http://blog.hoegaerden.be/wp-content/uploads/image349.png"><img style="display: inline; border-width: 0px;" title="The final result: sales figures aggregated over different periods in time" src="http://blog.hoegaerden.be/wp-content/uploads/image_thumb80.png" border="0" alt="The final result: sales figures aggregated over different periods in time" width="700" height="82" /></a></p>
<h2>Conclusion</h2>
<p>In this article I’ve demonstrated a way to aggregate data over different periods in time, using T-SQL and Integration Services.  Obviously this method does not replace the flexibility that one gets when analyzing data stored in an OLAP cube, but it can be a practical method when you quickly need to provide aggregated data for management.</p>
<p>Have fun!</p>
<p>Valentino.</p>
<p><strong>References</strong></p>
<p><a title="Merge Join Transformation" href="http://msdn.microsoft.com/en-us/library/ms141775.aspx" target="_blank">Merge Join Data Flow Transformation</a></p>
<p><a title="Using Common Table Expressions" href="http://msdn.microsoft.com/en-us/library/ms190766.aspx" target="_blank">Common Table Expressions (CTEs)</a></p>
<p><a title="DATEADD (Transact-SQL)" href="http://msdn.microsoft.com/en-us/library/ms186819.aspx" target="_blank">DATEADD() function</a></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.hoegaerden.be%2F2010%2F08%2F26%2Fcalculating-lastxmonths-aggregations-using-t-sql-and-ssis%2F&amp;title=Calculating%20LastXMonths%20Aggregations%20Using%20T-SQL%20and%20SSIS" id="wpa2a_18"><img src="http://blog.hoegaerden.be/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.hoegaerden.be/2010/08/26/calculating-lastxmonths-aggregations-using-t-sql-and-ssis/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Put Some Images On Those SSRS Reports</title>
		<link>http://blog.hoegaerden.be/2010/07/07/put-some-images-on-those-ssrs-reports/</link>
		<comments>http://blog.hoegaerden.be/2010/07/07/put-some-images-on-those-ssrs-reports/#comments</comments>
		<pubDate>Wed, 07 Jul 2010 16:05:21 +0000</pubDate>
		<dc:creator>Valentino Vranken</dc:creator>
				<category><![CDATA[Reporting Services]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[Reporting Services 2008]]></category>
		<category><![CDATA[SSRS]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://blog.hoegaerden.be/2010/07/07/put-some-images-on-those-ssrs-reports/</guid>
		<description><![CDATA[On the forums I now and then encounter questions regarding images on SSRS reports.  Instead of re-inventing the wheel each time, I decided to write an article about the subject.  So in this article I’ll be discussing and demonstrating several different ways of how images can be put on a report. I’m using SQL Server [...]]]></description>
			<content:encoded><![CDATA[<p>On the forums I now and then encounter questions regarding images on SSRS reports.  Instead of re-inventing the wheel each time, I decided to write an article about the subject.  So in this article I’ll be discussing and demonstrating several different ways of how images can be put on a report.</p>
<p>I’m using SQL Server Reporting Services 2008 R2 CTP, more precisely version 10.50.1352.12, but the methods explained here will work on any SSRS 2008.  Furthermore I’m using the AdventureWorks2008R2 database, <a title="AdventureWorks 2008R2 RTM" href="http://msftdbprodsamples.codeplex.com/releases/view/45907" target="_blank">available at CodePlex</a>.</p>
<p>The resulting report, including image files, <a title="SSRS and images download" href="http://cid-81c8b064cbbe1698.office.live.com/self.aspx/.Public/blog/SSRS%5E_and%5E_images.zip" target="_blank">can be downloaded from my Skydrive</a>.</p>
<h2>The Scenario</h2>
<p>The marketing department has requested a product catalogue.  This catalogue should contain all products produced by our two daughter companies: The Canyon Peak and Great Falls Soft.  The catalogue should be grouped on company, with the next company&#8217;s products starting on a new page.</p>
<p>Further requirements are:</p>
<ol>
<li>
<ol>
<li>Each page needs an image in its header, with even pages displaying a different image than odd pages.</li>
<li>Each company has a logo.  The logo should be displayed in the company’s header.</li>
<li>Each product has a logo.  The logo should be displayed as part of the product details.</li>
</ol>
</li>
</ol>
<p>A design document containing the expected layout, including all image material, has been provided.</p>
<h2>The Data</h2>
<p>The following query provides us with all the data needed to produce the report:</p>
<p><a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a></p>
<pre class="code"><span style="color: blue;">SELECT </span><span style="color: red;">'The Canyon Peak' </span><span style="color: blue;">as </span>Company<span style="color: gray;">, </span><span style="color: red;">'TheCanyonPeak_logo.png' </span>CompanyLogo<span style="color: gray;">,
    </span><span style="color: red;">'The Canyon Peak company specializes in all kinds of bikes, such as touring and road bikes.' </span>CompanyDescription<span style="color: gray;">,
    </span>P<span style="color: gray;">.</span>Name <span style="color: blue;">as </span>Product<span style="color: gray;">, </span>PS<span style="color: gray;">.</span>Name <span style="color: blue;">as </span>Subcategory<span style="color: gray;">, </span>PC<span style="color: gray;">.</span>Name <span style="color: blue;">as </span>Category<span style="color: gray;">,
    </span>PP<span style="color: gray;">.</span>LargePhoto<span style="color: gray;">, </span>P<span style="color: gray;">.</span>ListPrice<span style="color: gray;">, </span>P<span style="color: gray;">.</span><span style="color: blue;">Weight</span><span style="color: gray;">, </span>P<span style="color: gray;">.</span>Size<span style="color: gray;">,
    </span>P<span style="color: gray;">.</span>SizeUnitMeasureCode<span style="color: gray;">, </span>P<span style="color: gray;">.</span>WeightUnitMeasureCode
<span style="color: blue;">FROM </span>Production<span style="color: gray;">.</span>Product <span style="color: blue;">AS </span>P
    <span style="color: gray;">INNER JOIN </span>Production<span style="color: gray;">.</span>ProductSubcategory <span style="color: blue;">AS </span>PS
        <span style="color: blue;">ON </span>PS<span style="color: gray;">.</span>ProductSubcategoryID <span style="color: gray;">= </span>P<span style="color: gray;">.</span>ProductSubcategoryID
    <span style="color: gray;">INNER JOIN </span>Production<span style="color: gray;">.</span>ProductCategory <span style="color: blue;">AS </span>PC
        <span style="color: blue;">ON </span>PC<span style="color: gray;">.</span>ProductCategoryID <span style="color: gray;">= </span>PS<span style="color: gray;">.</span>ProductCategoryID
    <span style="color: gray;">LEFT OUTER JOIN </span>Production<span style="color: gray;">.</span>ProductProductPhoto PPP
        <span style="color: blue;">ON </span>PPP<span style="color: gray;">.</span>ProductID <span style="color: gray;">= </span>P<span style="color: gray;">.</span>ProductID
    <span style="color: gray;">LEFT OUTER JOIN </span>Production<span style="color: gray;">.</span>ProductPhoto PP
        <span style="color: blue;">ON </span>PPP<span style="color: gray;">.</span>ProductPhotoID <span style="color: gray;">= </span>PP<span style="color: gray;">.</span>ProductPhotoID
<span style="color: blue;">WHERE </span>PC<span style="color: gray;">.</span>Name <span style="color: gray;">= </span><span style="color: red;">'Bikes' </span><span style="color: green;">--The Canyon Peak sells bikes
    </span><span style="color: gray;">and </span>PP<span style="color: gray;">.</span>ProductPhotoID <span style="color: gray;">&gt; </span>1 <span style="color: green;">--I don't want NO IMAGE AVAILABLE
</span><span style="color: blue;">UNION </span><span style="color: gray;">ALL
</span><span style="color: blue;">SELECT </span><span style="color: red;">'Great Falls Soft' </span><span style="color: blue;">as </span>Company<span style="color: gray;">, </span><span style="color: red;">'GreatFallsSoft_logo.png' </span>CompanyLogo<span style="color: gray;">,
    </span><span style="color: red;">'Great Falls Soft uses only the softest tissues available for those sporting clothes.  And on top of that, they''re waterproof.' </span>CompanyDescription<span style="color: gray;">,
    </span>P<span style="color: gray;">.</span>Name <span style="color: blue;">as </span>Product<span style="color: gray;">, </span>PS<span style="color: gray;">.</span>Name <span style="color: blue;">as </span>Subcategory<span style="color: gray;">, </span>PC<span style="color: gray;">.</span>Name <span style="color: blue;">as </span>Category<span style="color: gray;">,
    </span>PP<span style="color: gray;">.</span>LargePhoto<span style="color: gray;">, </span>P<span style="color: gray;">.</span>ListPrice<span style="color: gray;">, </span>P<span style="color: gray;">.</span><span style="color: blue;">Weight</span><span style="color: gray;">, </span>P<span style="color: gray;">.</span>Size<span style="color: gray;">,
    </span>P<span style="color: gray;">.</span>SizeUnitMeasureCode<span style="color: gray;">, </span>P<span style="color: gray;">.</span>WeightUnitMeasureCode
<span style="color: blue;">FROM </span>Production<span style="color: gray;">.</span>Product <span style="color: blue;">AS </span>P
    <span style="color: gray;">INNER JOIN </span>Production<span style="color: gray;">.</span>ProductSubcategory <span style="color: blue;">AS </span>PS
        <span style="color: blue;">ON </span>PS<span style="color: gray;">.</span>ProductSubcategoryID <span style="color: gray;">= </span>P<span style="color: gray;">.</span>ProductSubcategoryID
    <span style="color: gray;">INNER JOIN </span>Production<span style="color: gray;">.</span>ProductCategory <span style="color: blue;">AS </span>PC
        <span style="color: blue;">ON </span>PC<span style="color: gray;">.</span>ProductCategoryID <span style="color: gray;">= </span>PS<span style="color: gray;">.</span>ProductCategoryID
    <span style="color: gray;">LEFT OUTER JOIN </span>Production<span style="color: gray;">.</span>ProductProductPhoto PPP
        <span style="color: blue;">ON </span>PPP<span style="color: gray;">.</span>ProductID <span style="color: gray;">= </span>P<span style="color: gray;">.</span>ProductID
    <span style="color: gray;">LEFT OUTER JOIN </span>Production<span style="color: gray;">.</span>ProductPhoto PP
        <span style="color: blue;">ON </span>PPP<span style="color: gray;">.</span>ProductPhotoID <span style="color: gray;">= </span>PP<span style="color: gray;">.</span>ProductPhotoID
<span style="color: blue;">WHERE </span>PC<span style="color: gray;">.</span>Name <span style="color: gray;">= </span><span style="color: red;">'Clothing' </span><span style="color: green;">--Great Falls Soft sells clothes, waterstopping soft clothes
    </span><span style="color: gray;">and </span>PP<span style="color: gray;">.</span>ProductPhotoID <span style="color: gray;">&gt; </span>1 <span style="color: green;">--I don't want NO IMAGE AVAILABLE
</span><span style="color: blue;">ORDER BY </span>Category <span style="color: blue;">asc</span><span style="color: gray;">, </span>Subcategory <span style="color: blue;">asc</span><span style="color: gray;">, </span>Product <span style="color: blue;">asc</span><span style="color: gray;">;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>I’m not going into the details of this query.  Let’s just say that I’m manipulating data from the database in combination with some hardcoded data to get usable data for our example.  I’ve added some comments to make it clear what the query is doing.  If you have a look at its output, you’ll see that it produces a list of products with some additional fields.</p>
<p><a href="http://blog.hoegaerden.be/wp-content/uploads/image303.png"><img style="display: inline; border-width: 0px;" title="Results of the query" src="http://blog.hoegaerden.be/wp-content/uploads/image_thumb71.png" border="0" alt="Results of the query" width="700" height="72" /></a></p>
<h2>Different Ways Of Adding Images</h2>
<p>To get started, open up a SSRS solution, add a new report, add a data source connecting to your AdventureWorks 2008 R2 DB, and add a dataset using the above query.</p>
<h3>Embedding Images In Your Report</h3>
<p>The first way of adding images to a report that we’ll take a look at is by embedding them inside the report.  Looking at the scenario requirements described earlier, this is requirement 1.</p>
<p>Let’s add a header to the report.  In the BIDS menu, select <strong>Report</strong> &gt; <strong>Add Page Header</strong>.</p>
<p><img style="display: inline; border-width: 0px;" title="Adding a header to a report" src="http://blog.hoegaerden.be/wp-content/uploads/image304.png" border="0" alt="Adding a header to a report" width="265" height="178" /></p>
<p>If you don’t see the Report menu item, you probably have not selected your report.  Click your report in the Design view to select it.</p>
<p>From the Toolbox, drag the Image report item onto the header portion of the report.  Doing that will show a pop-up window, the Image Properties.  By default, the <strong>Select the image source </strong>combobox is set to <em>Embedded</em>.  Good, that’s what we need at this point.  What we now need to do is import an image into the report, using the <strong>Import</strong> button.</p>
<p>Clicking the Import button shows a common file Open dialog.  Our marketing department has given me two images for use in the header: Cloudy_banner.png and AnotherCloudy_banner.png.  Let’s select the first one.</p>
<p><img style="display: inline; border-width: 0px;" title="Adding an image to a report by using the Import button on the Image Properties window" src="http://blog.hoegaerden.be/wp-content/uploads/image305.png" border="0" alt="Adding an image to a report by using the Import button on the Image Properties window" width="625" height="434" /></p>
<p>If you don’t see any images, have a look at that filter dropdown as highlighted in the screenshot above.  By default this is set to JPEG files.</p>
<p>Here’s the result in the Image Properties:</p>
<p><img style="display: inline; border-width: 0px;" title="Image Properties with an image selected" src="http://blog.hoegaerden.be/wp-content/uploads/image306.png" border="0" alt="Image Properties with an image selected" width="585" height="532" /></p>
<p>On the Size page, select <em>Clip</em> instead of <em>Fit proportional</em>.  This is a setting that you’ll need to look at case per case.  For our header images, <em>Clip</em> is the most suitable option.</p>
<p><img style="display: inline; border-width: 0px;" title="Image Properties: set Display to Clip" src="http://blog.hoegaerden.be/wp-content/uploads/image307.png" border="0" alt="Image Properties: set Display to Clip" width="585" height="532" /></p>
<p>Close the Image Properties window and enlarge the image placeholder so that it occupies the whole header area:</p>
<p><img style="display: inline; border-width: 0px;" title="Image added to report header" src="http://blog.hoegaerden.be/wp-content/uploads/image308.png" border="0" alt="Image added to report header" width="544" height="180" /></p>
<p>As you can see, we now have an image in the header.  But we haven’t fully implemented the requirement yet.  The even pages should display a different image than the uneven ones.</p>
<p>To be able to do that, we’ll first add the second banner image to the report.  In the Report Data pane, locate the <em>Images</em> node and open it up.  You’ll notice that the image that we inserted earlier can be found here.</p>
<p><img style="display: inline; border-width: 0px;" title="The Images node in the Report Data pane shows all embedded images" src="http://blog.hoegaerden.be/wp-content/uploads/image309.png" border="0" alt="The Images node in the Report Data pane shows all embedded images" width="168" height="159" /></p>
<p>Right-click the <em>Images</em> node and select <strong>Add Image</strong>.</p>
<p><img style="display: inline; border-width: 0px;" title="Right-click Images node to add an embedded image to the report" src="http://blog.hoegaerden.be/wp-content/uploads/image310.png" border="0" alt="Right-click Images node to add an embedded image to the report" width="229" height="155" /></p>
<p>That opens up the familiar file Open dialog which was used to add the first image.  So I’m now selecting the file called AnotherCloudy_banner.png, after changing the default filter to PNG.  After clicking OK, the image gets added under the Images node.</p>
<p><img style="display: inline; border-width: 0px;" title="Second banner image added to the report" src="http://blog.hoegaerden.be/wp-content/uploads/image311.png" border="0" alt="Second banner image added to the report" width="190" height="64" /></p>
<p>With the second image added, all that remains to be done is tell the header that it should pick different images depending on the page number.</p>
<p>Right-click the image in the header and select <strong>Image Properties</strong>.  On the General page, when you click the dropdown of the setting called Use this image, you’ll notice that there are two values now.  These are the same values as displayed in the Report Data pane.  And these are the values to be used in the expression that we’ll create to rotate the images depending on page number.</p>
<p>Click the fx button next to the dropdown and enter the following expression:</p>
<pre class="code">=IIF(Globals!PageNumber <span style="color: blue;">Mod </span>2 = 0, <span style="color: #a31515;">"Cloudy_banner"</span>, <span style="color: #a31515;">"AnotherCloudy_banner"</span>)</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>This is a fairly simple expression, using the Mod operator and the IIF() function.  When page number can be divided by two, which means it’s an even page number, Cloudy_banner is displayed.  Otherwise the other banner is displayed.</p>
<p>That’s it, the report header is finished.  When you have a look at the report in Preview, it should now show the second banner on the first page – this is an uneven page.</p>
<p>To conclude this chapter I’d like to mention that this method is usually not the preferred one.  A <strong>disadvantage</strong> here is that the images are stored inside the report RDL and thus cannot be modified without altering the report itself.</p>
<p>Here’s the evidence:</p>
<pre class="code"> <span style="color: blue;">&lt;</span><span style="color: #a31515;">EmbeddedImages</span><span style="color: blue;">&gt;
    &lt;</span><span style="color: #a31515;">EmbeddedImage </span><span style="color: red;">Name</span><span style="color: blue;">=</span>"<span style="color: blue;">Cloudy_banner</span>"<span style="color: blue;">&gt;
      &lt;</span><span style="color: #a31515;">MIMEType</span><span style="color: blue;">&gt;</span>image/png<span style="color: blue;">&lt;/</span><span style="color: #a31515;">MIMEType</span><span style="color: blue;">&gt;
      &lt;</span><span style="color: #a31515;">ImageData</span><span style="color: blue;">&gt;</span>iVBORw0KGgoAAAANSUhEUgAABVsAAABaCAIAAA...</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>To have a look at the RDL yourself, just right-click the report in the <strong>Solution Explorer</strong> and select <em>View Code</em>.</p>
<p>On to requirement number two!</p>
<h3>Displaying Images Through A URL</h3>
<p>At the moment, the report body is still empty, so drag a Table onto it.  Put the Table in the upper-left corner, remove one of the columns so that two remain, remove the Header row and make it a bit wider.</p>
<p>Now set the <strong>DataSetName</strong> property of the Tablix to the name of your dataset, in my case that’s <em>dsProducts</em>.</p>
<p>The report should display the data grouped on company, so right-click on the line that says <em>Details</em> in the Row Groups window part at the bottom of the Design View.  Select <strong>Add Group &gt; Parent Group</strong>.</p>
<p><img style="display: inline; border-width: 0px;" title="Right-click the Details line in Row Groups to add a new parent group" src="http://blog.hoegaerden.be/wp-content/uploads/image312.png" border="0" alt="Right-click the Details line in Row Groups to add a new parent group" width="646" height="160" /></p>
<p>Group by Company and add a group header:</p>
<p><img style="display: inline; border-width: 0px;" title="Tablix grouping" src="http://blog.hoegaerden.be/wp-content/uploads/image313.png" border="0" alt="Tablix grouping" width="451" height="201" /></p>
<p>Remove the extra first column that just got generated:</p>
<p><img style="display: inline; border-width: 0px;" title="Remove unwanted column" src="http://blog.hoegaerden.be/wp-content/uploads/image314.png" border="0" alt="Remove unwanted column" width="646" height="189" /></p>
<p>We’ve now got an empty tablix with two columns, a Details row and a Company header row.  In our dataset, one of the fields is called <em>CompanyDescription</em>.  Hover the mouse pointer above the textbox in the top-right, click the small icon that appears and choose the field from the dropdown that appears when you click the icon.</p>
<p><img style="display: inline; border-width: 0px;" title="Click the small icon to get a list of fields" src="http://blog.hoegaerden.be/wp-content/uploads/image315.png" border="0" alt="Click the small icon to get a list of fields" width="299" height="64" /></p>
<p>To add the company’s logo, drag an Image from the Toolbox pane into the textbox on the left of the company description.  Doing this opens up the by now familiar Image Properties dialog.</p>
<p>Give it a good name, such as CompanyLogo, and select <em>External</em> as image source.</p>
<p>Click the fx button next to the <strong>Use this image</strong> box and enter an expression such as this one:</p>
<pre class="code">=<span style="color: #a31515;">"file:C:\vavr\test\" </span>+ Fields!CompanyLogo.Value</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>When using External as image source, the image expression should result in a valid URL, any valid URL.  In my example the files are located in a local folder called c:\vavr\test.  Keep in mind that, when you deploy the report to a server, the images should by located in that same folder, this time located on the server.</p>
<p><img style="display: inline; border-width: 0px;" title="The Image Properties configured to display an External image" src="http://blog.hoegaerden.be/wp-content/uploads/image316.png" border="0" alt="The Image Properties configured to display an External image" width="417" height="200" /></p>
<p>By default the image gets displayed using the <em>Fit Proportional </em>setting.  You can verify this in the <strong>Size</strong> page of the Image Properties.  We want the image to get fully displayed while maintaining the aspect ratio, so leave the setting as it is.  Close the image properties dialog.</p>
<p>Vertically enlarge the first row in our tablix to an acceptable size.  In my case the marketing department specified to use a height of 1.5 inches for the company logo.  With the image selected, locate the Size &gt; Height property and set it to “1,5in”.  Note that the decimal separator used here depends on your local settings.</p>
<p>Now have a look at the report in Preview:</p>
<p><img style="display: inline; border-width: 0px;" title="The report with company logos added" src="http://blog.hoegaerden.be/wp-content/uploads/image317.png" border="0" alt="The report with company logos added" width="664" height="328" /></p>
<p>Note that I’ve removed the borders of all textboxes by setting their <strong>BorderStyle </strong>property to <em>None</em>.</p>
<p>With the logo images implemented we have fulfilled requirement two.  On to number three.</p>
<h3>Retrieving Images From The Database</h3>
<p>In this last requirement we’ll have a look at displaying images that are retrieved from the database, also known as data-bound images.</p>
<p>The retrieving part is actually already implemented.  In our dataset there’s a field called <strong>LargePhoto</strong>, that one contains a picture of the product.</p>
<p>Let’s add some product details and a picture in that remaining blank row.  To get full control over layout I want to make the detail part of the tablix a freestyle part.  First merge the two cells together by selecting both of them, then right-click and choose <strong>Merge Cells</strong>.</p>
<p><img style="display: inline; border-width: 0px;" title="Merging two cells together in a tablix" src="http://blog.hoegaerden.be/wp-content/uploads/image318.png" border="0" alt="Merging two cells together in a tablix" width="686" height="632" /></p>
<p>Now select a <strong>Rectangle</strong> in the Toolbox pane and drop it into the merged area.  To add fields such as Subcategory and Product you can just select them from the <strong>Report Data </strong>pane and drop them inside the rectangle.  I’m also adding some additional labels and fields, as shown in the next screenshot.</p>
<p><img style="display: inline; border-width: 0px;" title="The product details in Design view" src="http://blog.hoegaerden.be/wp-content/uploads/image319.png" border="0" alt="The product details in Design view" width="347" height="196" /></p>
<p>As you can see I’ve modified the fonts a bit.  The rendered version:</p>
<p><img style="display: inline; border-width: 0px;" title="The rendered product details" src="http://blog.hoegaerden.be/wp-content/uploads/image320.png" border="0" alt="The rendered product details" width="306" height="187" /></p>
<p>This is the expression used for displaying the weight:</p>
<pre class="code">=IIF(
    IsNothing(Fields!Weight.Value),
    <span style="color: #a31515;">"unknown"</span>,
    Fields!Weight.Value &amp; <span style="color: #a31515;">" " </span>&amp; Fields!WeightUnitMeasureCode.Value
)</pre>
<p><a href="http://11011.net/software/vspaste"></a>And here’s the expression for the size field:</p>
<pre class="code">=Fields!Size.Value &amp; <span style="color: #a31515;">" " </span>&amp; Fields!SizeUnitMeasureCode.Value</pre>
<p>For the layout of the price field I’ve just entered C in the <strong>Format</strong> property of the textbox.</p>
<p>With the textual product details completed, all that remains to be done is adding the product image.</p>
<p>From the Toolbox pane, drag an <strong>Image</strong> into the remaining whitespace in the rectangle, next to the product details.  (You did keep some space available, right?)</p>
<p>Again we get the familiar Image Properties popup.  Give it a good name, like ProductImage, and select the image source that we haven’t used yet, <em>Database</em>.  In the <strong>Use this field </strong>dropdown, select <em>LargePhoto</em>, and select <em>image/gif</em> as <strong>MIME type</strong>.</p>
<p><strong>Note:</strong> the images are stored as GIF.  You can verify this by running a select on the Production.ProductPhoto table.  Looking at the LargePhotoFileName field we see that the extension is .gif.</p>
<p>There one textbox on the General page that’s still blank.  That one is called Tooltip.  Click the fx button next to it and enter following formula:</p>
<pre class="code">=Fields!Product.Value</pre>
<p><a href="http://11011.net/software/vspaste"></a>Click sufficient OK buttons until the properties dialog is gone, then resize the image placeholder so that it occupies the remaining whitespace.</p>
<p>Here’s what the result looks like in preview:</p>
<p><img style="display: inline; border-width: 0px;" title="The final report, with a tooltip on the product image" src="http://blog.hoegaerden.be/wp-content/uploads/image321.png" border="0" alt="The final report, with a tooltip on the product image" width="656" height="344" /></p>
<p>When hovering the mouse pointer above the product image, you’ll get a nice tooltip.</p>
<h2>Conclusion</h2>
<p>In this article I have illustrated the three possible methods of adding an image to your Reporting Services report.</p>
<p>Have fun!</p>
<p>Valentino.</p>
<p><strong>References</strong></p>
<p><a title="Adding Images to a Report" href="http://msdn.microsoft.com/en-us/library/ms156482.aspx" target="_blank">BOL: Adding Images to a Report</a></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.hoegaerden.be%2F2010%2F07%2F07%2Fput-some-images-on-those-ssrs-reports%2F&amp;title=Put%20Some%20Images%20On%20Those%20SSRS%20Reports" id="wpa2a_20"><img src="http://blog.hoegaerden.be/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.hoegaerden.be/2010/07/07/put-some-images-on-those-ssrs-reports/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

