<?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>tim laqua dot com &#187; bi</title>
	<atom:link href="http://timlaqua.com/tag/bi/feed/" rel="self" type="application/rss+xml" />
	<link>http://timlaqua.com</link>
	<description>Thoughts and Code from Tim Laqua</description>
	<lastBuildDate>Fri, 16 Mar 2012 16:48:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Automating PowerPivot Data Refresh in Sharepoint 2010</title>
		<link>http://timlaqua.com/2012/03/automating-powerpivot-data-refresh-in-sharepoint-2010/</link>
		<comments>http://timlaqua.com/2012/03/automating-powerpivot-data-refresh-in-sharepoint-2010/#comments</comments>
		<pubDate>Fri, 16 Mar 2012 00:56:57 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Scripts & Code]]></category>
		<category><![CDATA[bi]]></category>
		<category><![CDATA[business intelligence]]></category>
		<category><![CDATA[sharepoint]]></category>

		<guid isPermaLink="false">http://timlaqua.com/?p=977</guid>
		<description><![CDATA[Of course we want to do this, it's a fundamental requirement. Dear Sharepoint, please refresh my PowerPivot when the data is ready, not on some arbitrary schedule. Until this functionality is built-in, people will continue to hack away at it to figure out how to make this happen. Is this supported? Certainly not - so [...]]]></description>
			<content:encoded><![CDATA[<p>Of course we want to do this, it's a fundamental requirement.  Dear Sharepoint, please refresh my PowerPivot when the data is ready, not on some arbitrary schedule.  Until this functionality is built-in, people will continue to hack away at it to figure out how to make this happen.  Is this supported?  Certainly not - so continue at your own risk.</p>
<p>So the method we'll be using here is just to mimic what Sharepoint does when you check the box to "Also refresh as soon as possible" in the schedule configuration page.  To accomplish this we open the profiler, connect it to whatever instance our Sharepoint PowerPivot database is hosted on and filter you TextData to "%Schedule%" or filter to just the Sharepoint PowerPivot database (SP2010_PowerPivot_Service_Application in our case) - then open up your test PowerPivot schedule configuration, check the box, click OK, wait for the schedule history to come back up and then stop the trace.  Now you know you've got what you need, you just have to find it:</p>
<p><a href="http://timlaqua.com/wp-content/uploads/2012/03/Profiler-Events.jpg"><img src="http://timlaqua.com/wp-content/uploads/2012/03/Profiler-Events.jpg" alt="" title="Profiler Events" width="797" height="56" class="alignnone size-full wp-image-978" /></a><br />
<span id="more-977"></span><br />
So here we have Sharepoint asking for information about the schedule (identified by the ItemID from DataRefresh.Items) and then passing the data it received to PersistSchedule.  If you take a close look at the PersistSchedule parameters, the last one is @RunNow = 1.  So clearly, this is what we're after.  We went the most tedious route and manually looked up the ItemID in DataRefresh.Items:</p>

<div class="wp_syntax"><div class="code"><pre class="tsql" style="font-family:monospace;"><span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">NOCOUNT</span> <span style="color: #0000FF;">ON</span>
&nbsp;
<span style="color: #0000FF;">DECLARE</span> @ItemID <span style="color: #0000FF;">UNIQUEIDENTIFIER</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'30D39B0E-DA8B-489B-A713-3B29D208B51F'</span>
&nbsp;
<span style="color: #0000FF;">DECLARE</span>
	@ItemName <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">200</span><span style="color: #808080;">&#41;</span>,
	@SPSiteID <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">UNIQUEIDENTIFIER</span><span style="color: #808080;">&#93;</span>,
	@SPWebID <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">UNIQUEIDENTIFIER</span><span style="color: #808080;">&#93;</span>,	
	@LastModifiedBy <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">450</span><span style="color: #808080;">&#41;</span>,
	@ScheduleLastUpdatedBy <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">450</span><span style="color: #808080;">&#41;</span>,
	@UserIdentity <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">450</span><span style="color: #808080;">&#41;</span>,
	@EmailNotification <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span>, 
	@EmailList <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">450</span><span style="color: #808080;">&#41;</span>,
	@SecurityConfiguration <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">INT</span><span style="color: #808080;">&#93;</span>,
	@SSApplicationID <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">256</span><span style="color: #808080;">&#41;</span>,
	@ProcessAllDataSources <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span>,
	@RV <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIGINT</span><span style="color: #808080;">&#93;</span>,
	<span style="color: #008080;">-- Schedule info</span>
	@Enabled <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span>, 
	<span style="color: #008080;">-- Schedule details</span>
	@NextProcessDate <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">DATETIME</span><span style="color: #808080;">&#93;</span>,
	@ScheduleStartDate <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">DATETIME</span><span style="color: #808080;">&#93;</span>,
	@FrequencyKey <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1</span><span style="color: #808080;">&#41;</span>,
	@RepeatFrequency <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">INT</span><span style="color: #808080;">&#93;</span>,
	@Sunday <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span>,
	@Monday <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span>,
	@Tuesday <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span>,
	@Wednesday <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span>,
	@Thursday <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span>,
	@Friday <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span>,
	@Saturday <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span>,
	@Weekday <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span>, 
	@WeekendDay <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span>, 
	@<span style="color: #0000FF;">DAY</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span>, 
	@MonthlyPeriod <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">TINYINT</span><span style="color: #808080;">&#93;</span>, 
	@MonthlySpecificDay <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">INT</span><span style="color: #808080;">&#93;</span>, 
	@ProcessAfterBusinessHours <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span>, 
	@SpecificTime <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">DATETIME</span><span style="color: #808080;">&#93;</span>,
	@RunNow <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span>
&nbsp;
<span style="color: #0000FF;">DECLARE</span> @Schedule <span style="color: #0000FF;">TABLE</span> <span style="color: #808080;">&#40;</span>
	<span style="color: #808080;">&#91;</span>ItemID<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">UNIQUEIDENTIFIER</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>Enabled<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>RV<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIGINT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>ItemName<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">200</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>SPSiteID<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">UNIQUEIDENTIFIER</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>SPWebID<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">UNIQUEIDENTIFIER</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>UserIdentity<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">450</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>LastModifiedBy<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">450</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>EmailNotification<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>EmailList<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">450</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>SecurityConfiguration<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">INT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>SSApplicationID<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">256</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>ProcessAllDataSources<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>ScheduleDetailID<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">UNIQUEIDENTIFIER</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>ScheduleStartDate<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">DATETIME</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>FrequencyKey<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>RepeatFrequency<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">INT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>Sunday<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>Monday<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>Tuesday<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>Wednesday<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>Thursday<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>Friday<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>Saturday<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>WeekDay<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>WeekendDay<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span><span style="color: #0000FF;">DAY</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>MonthlyPeriod<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">TINYINT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>MonthlySpecificDay<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">INT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>ProcessAfterBusinessHours<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>SpecificTime<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">DATETIME</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NULL</span>
<span style="color: #808080;">&#41;</span>
&nbsp;
<span style="color: #0000FF;">INSERT</span> <span style="color: #0000FF;">INTO</span> @Schedule
<span style="color: #0000FF;">EXEC</span> DataRefresh.<span style="color: #202020;">GetSchedule</span> @ItemID
&nbsp;
<span style="color: #0000FF;">SELECT</span> 
	 @ItemName <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>ItemName<span style="color: #808080;">&#93;</span>
	,@SPSiteID <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>SPSiteID<span style="color: #808080;">&#93;</span>
	,@SPWebID <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>SPWebID<span style="color: #808080;">&#93;</span>
	,@LastModifiedBy <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>LastModifiedBy<span style="color: #808080;">&#93;</span>
	,@ScheduleLastUpdatedBy <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'DOMAIN<span style="color: #000099; font-weight: bold;">\t</span>laqua'</span>
	,@UserIdentity <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>UserIdentity<span style="color: #808080;">&#93;</span>
	,@EmailNotification <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>EmailNotification<span style="color: #808080;">&#93;</span>
	,@EmailList <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>EmailList<span style="color: #808080;">&#93;</span>
	,@SecurityConfiguration <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>SecurityConfiguration<span style="color: #808080;">&#93;</span>
	,@SSApplicationID <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>SSApplicationID<span style="color: #808080;">&#93;</span>
	,@ProcessAllDataSources <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>ProcessAllDataSources<span style="color: #808080;">&#93;</span>
	,@RV <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>RV<span style="color: #808080;">&#93;</span>
		<span style="color: #008080;">-- Schedule info</span>
	,@Enabled <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>Enabled<span style="color: #808080;">&#93;</span>
		<span style="color: #008080;">-- Schedule details</span>
	,@NextProcessDate <span style="color: #808080;">=</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">GETDATE</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">DATE</span><span style="color: #808080;">&#41;</span>
	,@ScheduleStartDate <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>ScheduleStartDate<span style="color: #808080;">&#93;</span>
	,@FrequencyKey <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>FrequencyKey<span style="color: #808080;">&#93;</span>
	,@RepeatFrequency <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>RepeatFrequency<span style="color: #808080;">&#93;</span>
	,@Sunday <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>Sunday<span style="color: #808080;">&#93;</span>
	,@Monday <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>Monday<span style="color: #808080;">&#93;</span>
	,@Tuesday <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>Tuesday<span style="color: #808080;">&#93;</span>
	,@Wednesday <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>Wednesday<span style="color: #808080;">&#93;</span>
	,@Thursday <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>Thursday<span style="color: #808080;">&#93;</span>
	,@Friday <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>Friday<span style="color: #808080;">&#93;</span>
	,@Saturday <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>Saturday<span style="color: #808080;">&#93;</span>
	,@Weekday <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>Weekday<span style="color: #808080;">&#93;</span>
	,@WeekendDay <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>WeekendDay<span style="color: #808080;">&#93;</span>
	,@<span style="color: #0000FF;">DAY</span> <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">DAY</span><span style="color: #808080;">&#93;</span>
	,@MonthlyPeriod <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>MonthlyPeriod<span style="color: #808080;">&#93;</span>
	,@MonthlySpecificDay <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>MonthlySpecificDay<span style="color: #808080;">&#93;</span>
	,@ProcessAfterBusinessHours <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>ProcessAfterBusinessHours<span style="color: #808080;">&#93;</span>
	,@SpecificTime <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>SpecificTime<span style="color: #808080;">&#93;</span>
	,@RunNow <span style="color: #808080;">=</span> <span style="color: #000;">1</span>
<span style="color: #0000FF;">FROM</span> @Schedule
&nbsp;
<span style="color: #0000FF;">EXEC</span> DataRefresh.<span style="color: #202020;">PersistSchedule</span>
	 @ItemID <span style="color: #808080;">=</span> @ItemID
	,@ItemName <span style="color: #808080;">=</span> @ItemName
	,@SPSiteID <span style="color: #808080;">=</span> @SPSiteID
	,@SPWebID <span style="color: #808080;">=</span> @SPWebID
	,@LastModifiedBy <span style="color: #808080;">=</span> @LastModifiedBy
	,@ScheduleLastUpdatedBy <span style="color: #808080;">=</span> @ScheduleLastUpdatedBy
	,@UserIdentity <span style="color: #808080;">=</span> @UserIdentity
	,@EmailNotification <span style="color: #808080;">=</span> @EmailNotification
	,@EmailList <span style="color: #808080;">=</span> @EmailList
	,@SecurityConfiguration <span style="color: #808080;">=</span> @SecurityConfiguration
	,@SSApplicationID <span style="color: #808080;">=</span> @SSApplicationID
	,@ProcessAllDataSources <span style="color: #808080;">=</span> @ProcessAllDataSources
	,@RV <span style="color: #808080;">=</span> @RV
		<span style="color: #008080;">-- Schedule info</span>
	,@Enabled <span style="color: #808080;">=</span> @Enabled
		<span style="color: #008080;">-- Schedule details</span>
	,@NextProcessDate <span style="color: #808080;">=</span> @NextProcessDate
	,@ScheduleStartDate <span style="color: #808080;">=</span> @ScheduleStartDate
	,@FrequencyKey <span style="color: #808080;">=</span> @FrequencyKey
	,@RepeatFrequency <span style="color: #808080;">=</span> @RepeatFrequency
	,@Sunday <span style="color: #808080;">=</span> @Sunday
	,@Monday <span style="color: #808080;">=</span> @Monday
	,@Tuesday <span style="color: #808080;">=</span> @Tuesday
	,@Wednesday <span style="color: #808080;">=</span> @Wednesday
	,@Thursday <span style="color: #808080;">=</span> @Thursday
	,@Friday <span style="color: #808080;">=</span> @Friday
	,@Saturday <span style="color: #808080;">=</span> @Saturday
	,@Weekday <span style="color: #808080;">=</span> @Weekday
	,@WeekendDay <span style="color: #808080;">=</span> @WeekendDay
	,@<span style="color: #0000FF;">DAY</span> <span style="color: #808080;">=</span> @<span style="color: #0000FF;">DAY</span>
	,@MonthlyPeriod <span style="color: #808080;">=</span> @MonthlyPeriod
	,@MonthlySpecificDay <span style="color: #808080;">=</span> @MonthlySpecificDay
	,@ProcessAfterBusinessHours <span style="color: #808080;">=</span> @ProcessAfterBusinessHours
	,@SpecificTime <span style="color: #808080;">=</span> @SpecificTime
	,@RunNow <span style="color: #808080;">=</span> @RunNow</pre></div></div>

<p>The only parameters that don't come from GetSchedule are NextRunDate which we set to midnight of today and RunNow which is, of course, 1 and ScheduleLastModifiedBy (I just tossed my username in there, I assume you could use the system identity as well).</p>
<p>And then we set it up to refresh every 10 minutes via Agent job to test:</p>
<p><a href="http://timlaqua.com/wp-content/uploads/2012/03/Schedule-History.jpg"><img src="http://timlaqua.com/wp-content/uploads/2012/03/Schedule-History.jpg" alt="" title="Schedule History" width="535" height="365" class="alignnone size-full wp-image-979" /></a></p>
<p>Happy refreshing!  Let me know if you have any questions.</p>
]]></content:encoded>
			<wfw:commentRss>http://timlaqua.com/2012/03/automating-powerpivot-data-refresh-in-sharepoint-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slowly Changing Dimensions with MD5 Hashes in SSIS</title>
		<link>http://timlaqua.com/2012/02/slowly-changing-dimensions-with-md5-hashes-in-ssis/</link>
		<comments>http://timlaqua.com/2012/02/slowly-changing-dimensions-with-md5-hashes-in-ssis/#comments</comments>
		<pubDate>Mon, 27 Feb 2012 14:15:27 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[How-to Guides]]></category>
		<category><![CDATA[Scripts & Code]]></category>
		<category><![CDATA[Thoughts]]></category>
		<category><![CDATA[bi]]></category>
		<category><![CDATA[business intelligence]]></category>
		<category><![CDATA[data warehousing]]></category>

		<guid isPermaLink="false">http://timlaqua.com/?p=911</guid>
		<description><![CDATA[We recently moved away from the 3rd party Checksum component (and all 3rd party components) in SSIS and I wanted to share the pattern we settled on for maintaining our Type 1 Slowly Changing Dimensions (SCDs). There are two things we wanted to address with our new pattern. First, our previous implementation wasn't performing as [...]]]></description>
			<content:encoded><![CDATA[<p>We recently moved away from the 3rd party Checksum component (and all 3rd party components) in SSIS and I wanted to share the pattern we settled on for maintaining our Type 1 Slowly Changing Dimensions (SCDs).  There are two things we wanted to address with our new pattern.  First, our previous implementation wasn't performing as well as we needed it to or generating reliable checksums.  The second was that we wanted to get away from dependencies on custom assemblies in general.  To illustrate the pattern, we're going to build a SCD package off the Adventure Works DW DimCustomer table and skip over the actual source of the business keys and attributes by selecting directly from the completed dimension for now.</p>
<p>First, we assume that our dimension already exists (and we were using some other checksum or MERGE to maintain it).  We have to add a column to store the MD5 hash:</p>

<div class="wp_syntax"><div class="code"><pre class="tsql" style="font-family:monospace;"><span style="color: #0000FF;">ALTER</span> <span style="color: #0000FF;">TABLE</span> dbo.<span style="color: #202020;">DimCustomer</span> <span style="color: #0000FF;">ADD</span>
	MD5 <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">34</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span> <span style="color: #0000FF;">DEFAULT</span> <span style="color: #FF0000;">''</span></pre></div></div>

<p>Second, we need a staging table to store updated/changed rows.  Script out the current dimension as a CREATE, remove all unneeded constraints and indexes, and create a staging table as a heap:</p>

<div class="wp_syntax"><div class="code"><pre class="tsql" style="font-family:monospace;"><span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">TABLE</span> <span style="color: #808080;">&#91;</span>dbo<span style="color: #808080;">&#93;</span>.<span style="color: #808080;">&#91;</span>Staging_DimCustomer_UpdatedRows<span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span>
	<span style="color: #808080;">&#91;</span>CustomerKey<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">INT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>GeographyKey<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">INT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>CustomerAlternateKey<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">15</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>Title<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">8</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>FirstName<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">50</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>MiddleName<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">50</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>LastName<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">50</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>NameStyle<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">BIT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>BirthDate<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">DATETIME</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>MaritalStatus<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>Suffix<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">10</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>Gender<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>EmailAddress<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">50</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>YearlyIncome<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">MONEY</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>TotalChildren<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">TINYINT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>NumberChildrenAtHome<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">TINYINT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>EnglishEducation<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">40</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>SpanishEducation<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">40</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>FrenchEducation<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">40</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>EnglishOccupation<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">100</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>SpanishOccupation<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">100</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>FrenchOccupation<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">100</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>HouseOwnerFlag<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>NumberCarsOwned<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">TINYINT</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>AddressLine1<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">120</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>AddressLine2<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">120</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>Phone<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">20</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>DateFirstPurchase<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">DATETIME</span><span style="color: #808080;">&#93;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>CommuteDistance<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">15</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NULL</span>,
	<span style="color: #808080;">&#91;</span>MD5<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #000;">34</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><span style="color: #808080;">&#41;</span></pre></div></div>

<p>Now in to SSIS - We will be building:</p>
<ol>
<li>Execute SQL Task to Truncate our Staging table(s)</li>
<li>Data Flow Task to Insert new rows and Stage updated rows</li>
<ol>
<li>OLE DB Source to retrieve our source data</li>
<li>Script Component to Generate Row Numbers</li>
<li>Conditional Split to Evenly Distribute Rows</li>
<li>Script Component to Generate MD5 Hashes</li>
<li>Union All to Squish it all back together</li>
<li>Lookup to get the existing MD5 Hash (if it exists)</li>
<li>Conditional Split to separate Unchanged and Changed rows</li>
<li>RowCount Transformation </li>
<li>OLE DB Destination for Changed rows</li>
<li>OLE DB Destination for New rows</li>
</ol>
<li>Execute SQL Task to Update changed rows</li>
</ol>
<p><em>Completed Control Flow</em><br />
<a href="http://timlaqua.com/wp-content/uploads/2012/02/CompletedControlFlow.png"><img src="http://timlaqua.com/wp-content/uploads/2012/02/CompletedControlFlow.png" alt="" title="CompletedControlFlow" width="268" height="229" class="alignnone size-full wp-image-925" /></a></p>
<p><em>Completed Data Flow</em><br />
<a href="http://timlaqua.com/wp-content/uploads/2012/02/CompletedDataFlow.png"><img src="http://timlaqua.com/wp-content/uploads/2012/02/CompletedDataFlow.png" alt="" title="CompletedDataFlow" width="619" height="636" class="alignnone size-full wp-image-926" /></a></p>
<p><span id="more-911"></span></p>
<h5>1: Execute SQL Task to Truncate our Staging table(s)</h5>

<div class="wp_syntax"><div class="code"><pre class="tsql" style="font-family:monospace;"><span style="color: #0000FF;">TRUNCATE</span> <span style="color: #0000FF;">TABLE</span> Staging_DimCustomer_UpdatedRows;</pre></div></div>

<h5>2.1: OLE DB Source to retrieve our source data</h5>
<p><em>Configure the Connection Manager - for the source we'll just select from the dimension minus the surrogate key and MD5 column:</em><br />
<a href="http://timlaqua.com/wp-content/uploads/2012/02/2-1-Query1.png"><img src="http://timlaqua.com/wp-content/uploads/2012/02/2-1-Query1.png" alt="" title="2-1 Query" width="832" height="721" class="alignnone size-full wp-image-954" /></a></p>
<p><em>You most likely won't need to exclude any columns - here we unselect the surrogate key and the MD5 column:</em><br />
<a href="http://timlaqua.com/wp-content/uploads/2012/02/2-1-Columns.png"><img src="http://timlaqua.com/wp-content/uploads/2012/02/2-1-Columns.png" alt="" title="2-1 Columns" width="831" height="719" class="alignnone size-full wp-image-934" /></a></p>
<h5>2.2: Script Component to Generate Row Numbers</h5>
<p><em>Add one output column to Output 0 in your Row Number Script Transformation</em><br />
<a href="http://timlaqua.com/wp-content/uploads/2012/02/2-2-Output-Column.png"><img src="http://timlaqua.com/wp-content/uploads/2012/02/2-2-Output-Column.png" alt="" title="2-2 Output Column" width="838" height="724" class="alignnone size-full wp-image-936" /></a></p>
<p><em>The following code will assign the current row number and increment it for the next row through the buffer:</em></p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">using</span> <span style="color: #008080;">System</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.Data</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">using</span> <span style="color: #008080;">Microsoft.SqlServer.Dts.Pipeline.Wrapper</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">using</span> <span style="color: #008080;">Microsoft.SqlServer.Dts.Runtime.Wrapper</span><span style="color: #008000;">;</span>
&nbsp;
<span style="color: #000000;">&#91;</span>Microsoft.<span style="color: #0000FF;">SqlServer</span>.<span style="color: #0000FF;">Dts</span>.<span style="color: #0000FF;">Pipeline</span>.<span style="color: #0000FF;">SSISScriptComponentEntryPointAttribute</span><span style="color: #000000;">&#93;</span>
<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">class</span> ScriptMain <span style="color: #008000;">:</span> UserComponent
<span style="color: #000000;">&#123;</span>
    <span style="color: #0600FF;">private</span> <span style="color: #FF0000;">int</span> _rowCount <span style="color: #008000;">=</span> <span style="color: #FF0000;">1</span><span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">override</span> <span style="color: #0600FF;">void</span> Input0_ProcessInputRow<span style="color: #000000;">&#40;</span>Input0Buffer Row<span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
        Row.<span style="color: #0000FF;">RowNumber</span> <span style="color: #008000;">=</span> _rowCount<span style="color: #008000;">++;</span>
    <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<h5>2.3: Conditional Split to Evenly Distribute Rows</h5>
<p><em>Now in the conditional split, we distribute rows across multiple outputs by using the modulo operator.  Modify to suit the number of threads you need to remove any bottlenecks in the MD5 calculation (you may only need one thread):</em><br />
<a href="http://timlaqua.com/wp-content/uploads/2012/02/2-3-Conditional-Split-Outputs.png"><img src="http://timlaqua.com/wp-content/uploads/2012/02/2-3-Conditional-Split-Outputs.png" alt="" title="2-3 Conditional Split Outputs" width="742" height="721" class="alignnone size-full wp-image-937" /></a></p>
<h5>2.4: Script Component to Generate MD5 Hashes</h5>
<p><em>Add one output column to Output 0 in your Generate MD5 Script Transformation</em><br />
<a href="http://timlaqua.com/wp-content/uploads/2012/02/2-4-Output-Columns.png"><img src="http://timlaqua.com/wp-content/uploads/2012/02/2-4-Output-Columns.png" alt="" title="2-4 Output Columns" width="832" height="721" class="alignnone size-full wp-image-938" /></a></p>
<p>Select all input columns or just select ones that are going to be in the hash.  Since we explicitly specify columns in the script, the hash will only be generated with exactly what columns you tell it to use.</p>
<p><em>The following script will generate a string representation of a MD5 hash.  We do this so that we can do direct comparisons with HASHBYTES converted output (and virtually everything likes dealing with strings better than binary).  We do end up doubling the storage cost of the MD5 hash by storing it as a string, but we were fine with that:</em></p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">using</span> <span style="color: #008080;">System</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.Data</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">using</span> <span style="color: #008080;">Microsoft.SqlServer.Dts.Pipeline.Wrapper</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">using</span> <span style="color: #008080;">Microsoft.SqlServer.Dts.Runtime.Wrapper</span><span style="color: #008000;">;</span>
&nbsp;
<span style="color: #000000;">&#91;</span>Microsoft.<span style="color: #0000FF;">SqlServer</span>.<span style="color: #0000FF;">Dts</span>.<span style="color: #0000FF;">Pipeline</span>.<span style="color: #0000FF;">SSISScriptComponentEntryPointAttribute</span><span style="color: #000000;">&#93;</span>
<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">class</span> ScriptMain <span style="color: #008000;">:</span> UserComponent
<span style="color: #000000;">&#123;</span>
    <span style="color: #0600FF;">private</span> <span style="color: #000000;">System.<span style="color: #0000FF;">Security</span>.<span style="color: #0000FF;">Cryptography</span></span>.<span style="color: #0000FF;">MD5</span> _md5 <span style="color: #008000;">=</span>
                <span style="color: #008000;">new</span> <span style="color: #000000;">System.<span style="color: #0000FF;">Security</span>.<span style="color: #0000FF;">Cryptography</span></span>.<span style="color: #0000FF;">MD5CryptoServiceProvider</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">override</span> <span style="color: #0600FF;">void</span> Input0_ProcessInputRow<span style="color: #000000;">&#40;</span>Input0Buffer Row<span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
        <span style="color: #0600FF;">try</span>
        <span style="color: #000000;">&#123;</span>
            <span style="color: #FF0000;">string</span> hashSource <span style="color: #008000;">=</span>
                <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">GeographyKey_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">GeographyKey</span>.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">Title_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">Title</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">FirstName_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">FirstName</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">MiddleName_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">MiddleName</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">LastName_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">LastName</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">NameStyle_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">NameStyle</span>.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">BirthDate_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">BirthDate</span>.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">MaritalStatus_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">MaritalStatus</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">Suffix_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">Suffix</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">Gender_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">Gender</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">EmailAddress_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">EmailAddress</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">YearlyIncome_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">YearlyIncome</span>.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">TotalChildren_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">TotalChildren</span>.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">NumberChildrenAtHome_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">NumberChildrenAtHome</span>.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">EnglishEducation_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">EnglishEducation</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">SpanishEducation_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">SpanishEducation</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">FrenchEducation_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">FrenchEducation</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">EnglishOccupation_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">EnglishOccupation</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">SpanishOccupation_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">SpanishOccupation</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">FrenchOccupation_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">FrenchOccupation</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">HouseOwnerFlag_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">HouseOwnerFlag</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">NumberCarsOwned_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">NumberCarsOwned</span>.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">AddressLine1_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">AddressLine1</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">AddressLine2_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">AddressLine2</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">Phone_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">Phone</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">DateFirstPurchase_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">DateFirstPurchase</span>.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">+</span> <span style="color: #000000;">&#40;</span>Row.<span style="color: #0000FF;">CommuteDistance_IsNull</span> <span style="color: #008000;">?</span> <span style="color: #666666;">&quot;&quot;</span> <span style="color: #008000;">:</span> Row.<span style="color: #0000FF;">CommuteDistance</span><span style="color: #000000;">&#41;</span>
                <span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #FF0000;">byte</span><span style="color: #000000;">&#91;</span><span style="color: #000000;">&#93;</span> hashBytes <span style="color: #008000;">=</span> _md5.<span style="color: #0000FF;">ComputeHash</span><span style="color: #000000;">&#40;</span>
                <span style="color: #000000;">System.<span style="color: #0000FF;">Text</span></span>.<span style="color: #0000FF;">UnicodeEncoding</span>.<span style="color: #0000FF;">Unicode</span>.<span style="color: #0000FF;">GetBytes</span><span style="color: #000000;">&#40;</span>hashSource<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #000000;">System.<span style="color: #0000FF;">Text</span></span>.<span style="color: #0000FF;">StringBuilder</span> sb <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> <span style="color: #000000;">System.<span style="color: #0000FF;">Text</span></span>.<span style="color: #0000FF;">StringBuilder</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #0600FF;">for</span> <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span> i <span style="color: #008000;">=</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">;</span> i <span style="color: #008000;">&lt;</span> hashBytes.<span style="color: #0000FF;">Length</span><span style="color: #008000;">;</span> i<span style="color: #008000;">++</span><span style="color: #000000;">&#41;</span>
            <span style="color: #000000;">&#123;</span>
                sb.<span style="color: #0000FF;">Append</span><span style="color: #000000;">&#40;</span>hashBytes<span style="color: #000000;">&#91;</span>i<span style="color: #000000;">&#93;</span>.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;X2&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #000000;">&#125;</span>
&nbsp;
            Row.<span style="color: #0000FF;">MD5</span> <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;0x&quot;</span> <span style="color: #008000;">+</span> sb.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #000000;">&#125;</span>
        <span style="color: #0600FF;">catch</span> <span style="color: #000000;">&#40;</span>Exception e<span style="color: #000000;">&#41;</span>
        <span style="color: #000000;">&#123;</span>
            Row.<span style="color: #0000FF;">MD5</span> <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;Error&quot;</span><span style="color: #008000;">;</span>
        <span style="color: #000000;">&#125;</span>
    <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>To quickly generate the string concatenation statement:</p>
<ol>
<li>Script DimCustomer As SELECT to Clipboard and paste in to Notepad++</li>
<li>Search > Replace... (Ctrl+H)</li>
<li>Select Regular expression for Search Mode</li>
<li><strong>Find:</strong> ^.*?\[(.*?)\].*$</li>
<li><strong>Replace:</strong> + (Row.\1_IsNull ? "" : Row.\1)</li>
<li>Replace All, remove the leading +, and remove the garbage at the bottom, remove surrogate and business keys</li>
<li>Paste results in to the script</li>
<li>Add .ToString() to non-string columns and fix any column names (issues will be underlined in red)</li>
</ol>
<p>Copy your completed script component once for each thread you'll be running.  When you copy a script component, you need to actually open the script after copying it and click Edit Script before it will validate.</p>
<h5>2.5: Union All to Squish it all back together</h5>
<h5>2.6: Lookup to get the existing MD5 Hash (if it exists)</h5>
<p><em>Configure the Lookup component to redirect rows with no matches to the No Match output:</em><br />
<a href="http://timlaqua.com/wp-content/uploads/2012/02/2-6-Redirect-Rows-to-No-Match.png"><img src="http://timlaqua.com/wp-content/uploads/2012/02/2-6-Redirect-Rows-to-No-Match.png" alt="" title="2-6 Redirect Rows to No Match" width="832" height="721" class="alignnone size-full wp-image-941" /></a></p>
<p><em>For your connection, select the surrogate key, business key(s), and MD5 hash from your existing dimension table:</em><br />
<a href="http://timlaqua.com/wp-content/uploads/2012/02/2-6-Connection-Settings.png"><img src="http://timlaqua.com/wp-content/uploads/2012/02/2-6-Connection-Settings.png" alt="" title="2-6 Connection Settings" width="832" height="721" class="alignnone size-full wp-image-940" /></a></p>
<p><em>Lookup based on the business key(s) and bring back the existing MD5 and surrogate key</em><br />
<a href="http://timlaqua.com/wp-content/uploads/2012/02/2-6-Column-Settings.png"><img src="http://timlaqua.com/wp-content/uploads/2012/02/2-6-Column-Settings.png" alt="" title="2-6 Column Settings" width="832" height="721" class="alignnone size-full wp-image-939" /></a></p>
<h5>2.7: Conditional Split to separate Unchanged and Changed rows</h5>
<p><em>Name the output for rows where the ExistingMD5 is the same as the new MD5 "Ignore" and name the Default output "Update"</em><br />
<a href="http://timlaqua.com/wp-content/uploads/2012/02/2-7-Conditional-Outputs.png"><img src="http://timlaqua.com/wp-content/uploads/2012/02/2-7-Conditional-Outputs.png" alt="" title="2-7 Conditional Outputs" width="742" height="721" class="alignnone size-full wp-image-942" /></a></p>
<h5>2.8: RowCount Transformation for Ignored Rows</h5>
<p><em>For your Ignored Rows Row Count transformation, you'll have to create a variable to store the rowcount in (we don't use it, but that's just how the transformation works):</em><br />
<a href="http://timlaqua.com/wp-content/uploads/2012/02/2-8-Ignored-Rows-Settings.png"><img src="http://timlaqua.com/wp-content/uploads/2012/02/2-8-Ignored-Rows-Settings.png" alt="" title="2-8 Ignored Rows Settings" width="799" height="721" class="alignnone size-full wp-image-943" /></a></p>
<h5>2.9: OLE DB Destination for Changed rows</h5>
<p><em>We'll insert rows that need to be updated in to the previously created Staging_DimCustomer_UpdatedRows table:</em><br />
<a href="http://timlaqua.com/wp-content/uploads/2012/02/2-9-Connection-Manager.png"><img src="http://timlaqua.com/wp-content/uploads/2012/02/2-9-Connection-Manager.png" alt="" title="2-9 Connection Manager" width="832" height="721" class="alignnone size-full wp-image-944" /></a></p>
<h5>2.10: OLE DB Destination for New rows</h5>
<p><em>Finally, insert new rows directly in to the dimension:</em><br />
<a href="http://timlaqua.com/wp-content/uploads/2012/02/2-10-Connection-Manager.png"><img src="http://timlaqua.com/wp-content/uploads/2012/02/2-10-Connection-Manager.png" alt="" title="2-10 Connection Manager" width="832" height="721" class="alignnone size-full wp-image-945" /></a></p>
<h5>3: Execute SQL Task to Update changed rows</h5>
<p><em>The final step is to take those rows we staged for updating and actually perform the update:</em></p>

<div class="wp_syntax"><div class="code"><pre class="tsql" style="font-family:monospace;"><span style="color: #0000FF;">UPDATE</span> a <span style="color: #0000FF;">SET</span>
 <span style="color: #808080;">&#91;</span>GeographyKey<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>GeographyKey<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>CustomerAlternateKey<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>CustomerAlternateKey<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>Title<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>Title<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>FirstName<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>FirstName<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>MiddleName<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>MiddleName<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>LastName<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>LastName<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>NameStyle<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>NameStyle<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>BirthDate<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>BirthDate<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>MaritalStatus<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>MaritalStatus<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>Suffix<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>Suffix<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>Gender<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>Gender<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>EmailAddress<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>EmailAddress<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>YearlyIncome<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>YearlyIncome<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>TotalChildren<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>TotalChildren<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>NumberChildrenAtHome<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>NumberChildrenAtHome<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>EnglishEducation<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>EnglishEducation<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>SpanishEducation<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>SpanishEducation<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>FrenchEducation<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>FrenchEducation<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>EnglishOccupation<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>EnglishOccupation<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>SpanishOccupation<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>SpanishOccupation<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>FrenchOccupation<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>FrenchOccupation<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>HouseOwnerFlag<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>HouseOwnerFlag<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>NumberCarsOwned<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>NumberCarsOwned<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>AddressLine1<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>AddressLine1<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>AddressLine2<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>AddressLine2<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>Phone<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>Phone<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>DateFirstPurchase<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>DateFirstPurchase<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>CommuteDistance<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>CommuteDistance<span style="color: #808080;">&#93;</span>
,<span style="color: #808080;">&#91;</span>MD5<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>MD5<span style="color: #808080;">&#93;</span> 
<span style="color: #0000FF;">FROM</span> DimCustomer a
	 <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span> Staging_DimCustomer_UpdatedRows b
		<span style="color: #0000FF;">ON</span> a.<span style="color: #202020;">CustomerKey</span> <span style="color: #808080;">=</span> b.<span style="color: #202020;">CustomerKey</span></pre></div></div>

<p>To quickly generate the update statement:</p>
<ol>
<li>Script DimCustomer As SELECT to Clipboard and paste in to Notepad++</li>
<li>Search > Replace... (Ctrl+H)</li>
<li>Select Regular expression for Search Mode</li>
<li><strong>Find:</strong> ^.*?\[(.*?)\].*$</li>
<li><strong>Replace:</strong> ,[\1] = b.[\1]</li>
<li>Replace All, remove surrogate key and garbage at the bottom, remove leading comma</li>
<li>Add UPDATE a SET at the top</li>
<li>Add appropriate FROM clause at the bottom</li>
</ol>
<p>And bob's your uncle.</p>
<h5>In closing...</h5>
<p><strong>Why not write a reusable code block for the MD5 hash that you could cut and paste?  Why hardcode columns?</strong><br />
Well, there's really only two ways to do it dynamically.  One is to loop over each column in the InputBuffer and concatenate them.  Man, that's a bunch of extra logic when we know very well what columns are, null handling is a little sketch, and proper datatype handling requires some special logic.  Looping over the InputBuffer also just plain feels dirty.  The second option is Reflection.  Now we could approach reflection two ways - first we could iterate over the Row definition and concatenate the columns for each InputRow, but this is INCREDIBLY expensive (reflection is crazy slow).  The second Reflection approach would be to construct a DynamicMethod at runtime and call that dynamic method for each row.  While this could certainly be as fast as hardcoding, it's very obscure and difficult for most people to understand.  Do you want code in your packages that's hard to understand?</p>
<p>We chose hardcode the columns because this is the absolute minimum amount of work that needs to be done to generate a reliable MD5 hash and is therefore the fastest possible solution.</p>
<p><strong>Why not do that Reflection and DynamicMethod thing in a custom transformation?</strong><br />
Because one of the main goals here was to rid ourselves of 3rd party dependencies (all custom assembly dependencies really) and we wanted to do the minimum amount of work required to generated a reliable MD5 hash.</p>
<p><strong>Why bulk update at the end rather than update each row via OLE DB Command?</strong><br />
Because the OLE DB Command isn't set based and it can block/be blocked by inserts.  Also, parameter mapping to all those Param_XX parameters and counting question marks is just terrible.  So, so terrible.</p>
<p><strong>How do I know how many threads I need to distribute the MD5 calculation over?</strong><br />
First we'll usually watch the source query in the database engine to see what it's waiting on.  PREEMPTIVE_OS_WAITFORSINGLEOBJECT tends to point at SQL Server waiting to send data to SSIS because it's not accepting rows fast enough.  For a starting point, take your source query and see how long it takes to just insert the entire thing in to a heap - somewhere around there is what we're shooting for.  Faster if you ignore many rows, slower if you update/insert many rows.</p>
<p><strong>How does it perform?</strong><br />
It's ridiculously fast.  One of our dimensions (55 columns, varying datatypes, ~5 million deep, ~4.5 million evaluated for changes 3 times a day) went from 50+ minutes per run to 5-9 minutes per run.  More importantly, we were previously using the CRC32 algorithm in the Checksum transform and that wasn't producing reliable checksums so we would either update unchanged rows or even miss changes to rows - now the hashes are dead on and reproducible via HASHBYTES.</p>
<p>As a side note, we were able to get Checksum to keep up with sql server by spreading it across 6 threads but the lack of reliable output forced us to abandon it.</p>
<p><strong>Is there a quick way to mimic the SSIS MD5 using HASHBYTES?</strong></p>
<ol>
<li>Script DimCustomer As SELECT to Clipboard and paste in to Notepad++</li>
<li>Search > Replace... (Ctrl+H)</li>
<li>Select Regular expression for Search Mode</li>
<li><strong>Find:</strong> ^.*?\[(.*?)\].*$</li>
<li><strong>Replace:</strong> +ISNULL(CAST([\1] AS NVARCHAR(255)),N'')</li>
<li>Replace All, remove surrogate key, business key(s), leading +, and garbage at the bottom</li>
<li>Add <strong>CONVERT(VARCHAR(34), HASHBYTES('md5',</strong> at the top</li>
<li>Add <strong>),1) AS [Hashbytes]</strong> and an appropriate FROM clause at the bottom</li>
</ol>
<p>Now if all your columns are chars, nchars, varchars, nvarchars, ints, and decimals - you're good.  If some of your columns are the more unique datatypes (datetime, money, bit, etc) - then you've got more work to do.  The issue lies in the difference between how sql server converts these datatypes to NVARCHAR and how C# converts them to strings.  Here are a few examples:</p>
<table cellpadding=0 cellspacing="0">
<tr>
<th>Datatype</th>
<th>SQL Conversion</th>
<th>C# Conversion</th>
</tr>
<tr>
<td>DATETIME</td>
<td>1966-04-08 00:00:00.000</td>
<td>4/8/1966 12:00:00 AM</td>
</tr>
<tr>
<td>MONEY</td>
<td>70000.00</td>
<td>70000</td>
</tr>
<tr>
<td>BIT</td>
<td>1</td>
<td>True</td>
</tr>
<tr>
<td>BIT</td>
<td>0</td>
<td>False</td>
</tr>
</table>
<p>The dates are the biggest debacle as they're sensitive to localization settings.  If you actually had to generate the hashes using HASHBYTES on a regular basis, we would recommend modifying the date formatting when concatenating columns for the hashSource variable in the script so they match sql server.  For us, we only generate MD5s using HASHBYTES for troubleshooting and updating the hash using purely dim columns rather than relying on the source as some business keys no longer exist in the source.</p>
<p><em>Here's the finished tsql for the above hash:</em></p>

<div class="wp_syntax"><div class="code"><pre class="tsql" style="font-family:monospace;"><span style="color: #0000FF;">SELECT</span> 
 CustomerKey
,CustomerAlternateKey
,MD5
,<span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">34</span><span style="color: #808080;">&#41;</span>, HASHBYTES<span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'md5'</span>,
IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>GeographyKey<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>Title<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>FirstName<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>MiddleName<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>LastName<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CASE</span> <span style="color: #0000FF;">WHEN</span> <span style="color: #808080;">&#91;</span>NameStyle<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> <span style="color: #000;">1</span> <span style="color: #0000FF;">THEN</span> N<span style="color: #FF0000;">'True'</span> <span style="color: #0000FF;">ELSE</span> N<span style="color: #FF0000;">'False'</span> <span style="color: #0000FF;">END</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span>
<span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">DATEPART</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">MONTH</span>,<span style="color: #808080;">&#91;</span>BirthDate<span style="color: #808080;">&#93;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">2</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span><span style="color: #FF0000;">'/'</span><span style="color: #808080;">+</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">DATEPART</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">DAY</span>,<span style="color: #808080;">&#91;</span>BirthDate<span style="color: #808080;">&#93;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">2</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span><span style="color: #FF0000;">'/'</span><span style="color: #808080;">+</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">DATEPART</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">YEAR</span>,<span style="color: #808080;">&#91;</span>BirthDate<span style="color: #808080;">&#93;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">4</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span><span style="color: #FF0000;">' '</span><span style="color: #808080;">+</span><span style="color: #0000FF;">LEFT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">RIGHT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">NVARCHAR</span>, <span style="color: #808080;">&#91;</span>BirthDate<span style="color: #808080;">&#93;</span>, <span style="color: #000;">109</span><span style="color: #808080;">&#41;</span>, <span style="color: #000;">14</span><span style="color: #808080;">&#41;</span>,<span style="color: #000;">8</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span><span style="color: #FF0000;">' '</span><span style="color: #808080;">+</span><span style="color: #0000FF;">RIGHT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">NVARCHAR</span>, <span style="color: #808080;">&#91;</span>BirthDate<span style="color: #808080;">&#93;</span>, <span style="color: #000;">109</span><span style="color: #808080;">&#41;</span>, <span style="color: #000;">2</span><span style="color: #808080;">&#41;</span>
,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>MaritalStatus<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>Suffix<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>Gender<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>EmailAddress<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>YearlyIncome <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">FLOAT</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>TotalChildren<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>NumberChildrenAtHome<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>EnglishEducation<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>SpanishEducation<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>FrenchEducation<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>EnglishOccupation<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>SpanishOccupation<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>FrenchOccupation<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>HouseOwnerFlag<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>NumberCarsOwned<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>AddressLine1<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>AddressLine2<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>Phone<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span>
<span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">DATEPART</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">MONTH</span>,DateFirstPurchase<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">2</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span><span style="color: #FF0000;">'/'</span><span style="color: #808080;">+</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">DATEPART</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">DAY</span>,DateFirstPurchase<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">2</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span><span style="color: #FF0000;">'/'</span><span style="color: #808080;">+</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">DATEPART</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">YEAR</span>,DateFirstPurchase<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">4</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span><span style="color: #FF0000;">' '</span><span style="color: #808080;">+</span><span style="color: #0000FF;">LEFT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">RIGHT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">NVARCHAR</span>, DateFirstPurchase, <span style="color: #000;">109</span><span style="color: #808080;">&#41;</span>, <span style="color: #000;">14</span><span style="color: #808080;">&#41;</span>,<span style="color: #000;">8</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span><span style="color: #FF0000;">' '</span><span style="color: #808080;">+</span><span style="color: #0000FF;">RIGHT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">NVARCHAR</span>, DateFirstPurchase, <span style="color: #000;">109</span><span style="color: #808080;">&#41;</span>, <span style="color: #000;">2</span><span style="color: #808080;">&#41;</span>
,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">+</span>IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>CommuteDistance<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,N<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span>
<span style="color: #808080;">&#41;</span>,<span style="color: #000;">1</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #808080;">&#91;</span>Hashbytes<span style="color: #808080;">&#93;</span>
<span style="color: #0000FF;">FROM</span> DimCustomer</pre></div></div>

<p><em>And the results:</em><br />
<a href="http://timlaqua.com/wp-content/uploads/2012/02/HASHBYTES-Results.png"><img src="http://timlaqua.com/wp-content/uploads/2012/02/HASHBYTES-Results.png" alt="" title="HASHBYTES Results" width="720" height="169" class="alignnone size-full wp-image-960" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://timlaqua.com/2012/02/slowly-changing-dimensions-with-md5-hashes-in-ssis/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Uncivil UNIONs</title>
		<link>http://timlaqua.com/2012/02/uncivil-unions/</link>
		<comments>http://timlaqua.com/2012/02/uncivil-unions/#comments</comments>
		<pubDate>Thu, 02 Feb 2012 16:12:43 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Thoughts]]></category>
		<category><![CDATA[bi]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://timlaqua.com/?p=878</guid>
		<description><![CDATA[If you asked any SQL Server Developer or DBA what UNION does, they would tell you it combines two result sets. Then if you were to ask them if they knew it removed duplicates without the ALL argument, they would say yes. That's academic, but I dare you to go look at their and your [...]]]></description>
			<content:encoded><![CDATA[<p>If you asked any SQL Server Developer or DBA what UNION does, they would tell you it combines two result sets.  Then if you were to ask them if they knew it removed duplicates without the ALL argument, they would say yes.  That's academic, but I dare you to go look at their and your code and see how often UNION without the ALL argument is used.  UNION is evil.  Why do I say that?  Because DISTINCT is evil and blocking operations are evil so it follows that UNION is evil.</p>
<p>Would you be OK with the following query as the source for a fact table?</p>

<div class="wp_syntax"><div class="code"><pre class="tsql" style="font-family:monospace;"><span style="color: #0000FF;">SELECT</span> <span style="color: #0000FF;">DISTINCT</span> <span style="color: #808080;">*</span>
<span style="color: #0000FF;">FROM</span>
<span style="color: #808080;">&#40;</span>
  <span style="color: #0000FF;">SELECT</span> <span style="color: #0000FF;">DISTINCT</span> <span style="color: #808080;">&#91;</span>c1<span style="color: #808080;">&#93;</span>,<span style="color: #808080;">&#91;</span>c2<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">FROM</span> <span style="color: #808080;">&#91;</span>t1<span style="color: #808080;">&#93;</span>
  <span style="color: #0000FF;">UNION</span> <span style="color: #808080;">ALL</span>
  <span style="color: #0000FF;">SELECT</span> <span style="color: #0000FF;">DISTINCT</span> <span style="color: #808080;">&#91;</span>c1<span style="color: #808080;">&#93;</span>,<span style="color: #808080;">&#91;</span>c2<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">FROM</span> <span style="color: #808080;">&#91;</span>t2<span style="color: #808080;">&#93;</span>
<span style="color: #808080;">&#41;</span> a</pre></div></div>

<p>No?  Then why are you OK with this?</p>

<div class="wp_syntax"><div class="code"><pre class="tsql" style="font-family:monospace;"><span style="color: #0000FF;">SELECT</span> <span style="color: #808080;">&#91;</span>c1<span style="color: #808080;">&#93;</span>,<span style="color: #808080;">&#91;</span>c2<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">FROM</span> <span style="color: #808080;">&#91;</span>t1<span style="color: #808080;">&#93;</span>
<span style="color: #0000FF;">UNION</span>
<span style="color: #0000FF;">SELECT</span> <span style="color: #808080;">&#91;</span>c1<span style="color: #808080;">&#93;</span>,<span style="color: #808080;">&#91;</span>c2<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">FROM</span> <span style="color: #808080;">&#91;</span>t2<span style="color: #808080;">&#93;</span></pre></div></div>

<p>Personally, I tend to use UNION to combine data from two different sources.  For example, if I wanted to combine the sales transactions from two JDE instances - the query might look like:</p>

<div class="wp_syntax"><div class="code"><pre class="tsql" style="font-family:monospace;"><span style="color: #0000FF;">SELECT</span> <span style="color: #808080;">&#91;</span>c1<span style="color: #808080;">&#93;</span>,<span style="color: #808080;">&#91;</span>c2<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">FROM</span> <span style="color: #808080;">&#91;</span>JDE1<span style="color: #808080;">&#93;</span>.<span style="color: #808080;">&#91;</span>dbo<span style="color: #808080;">&#93;</span>.<span style="color: #808080;">&#91;</span>F42119<span style="color: #808080;">&#93;</span>
<span style="color: #0000FF;">UNION</span>
<span style="color: #0000FF;">SELECT</span> <span style="color: #808080;">&#91;</span>c1<span style="color: #808080;">&#93;</span>,<span style="color: #808080;">&#91;</span>c2<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">FROM</span> <span style="color: #808080;">&#91;</span>JDE2<span style="color: #808080;">&#93;</span>.<span style="color: #808080;">&#91;</span>dbo<span style="color: #808080;">&#93;</span>.<span style="color: #808080;">&#91;</span>F42119<span style="color: #808080;">&#93;</span></pre></div></div>

<p>Each line here in a sales detail represents a line on an order, so assuming you selected all the PK columns in your query, a UNION won't remove any rows within either set, but when combined - it's possible the same PK could exist in both systems.  Now you could split hairs and say it's highly unlikely the rest of the row would be identical, but that's not the point - it's wrong to ever DISTINCT a set of transactions intended for creating a fact table.  Sure, in this particular case you could add a "SourceSystem" column that would stop that, but then you still have to accept that the UNION is blocking and expensive.  Just because a DISTINCT doesn't modify results doesn't mean it didn't do any work - it actually did a great deal of work.  Now consider that we're usually not selecting 2 columns, we're selecting 10-20. Do you want to wait for it to figure out all the rows are distinct when you already knew that?  Further, if they're not distinct you probably screwed up a JOIN somewhere.</p>
<p>As far as coding standards regarding UNION go, I would suggest never using UNION without the ALL clause and doing your DISTINCT elsewhere if that's actually what you intended.  Does that seem silly?  Yes - but I would wager you won't ever use the 2nd one outside of building Dimensions.</p>

<div class="wp_syntax"><div class="code"><pre class="tsql" style="font-family:monospace;"><span style="color: #0000FF;">SELECT</span> <span style="color: #808080;">&#91;</span>c1<span style="color: #808080;">&#93;</span>,<span style="color: #808080;">&#91;</span>c2<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">FROM</span> <span style="color: #808080;">&#91;</span>JDE1<span style="color: #808080;">&#93;</span>.<span style="color: #808080;">&#91;</span>dbo<span style="color: #808080;">&#93;</span>.<span style="color: #808080;">&#91;</span>F42119<span style="color: #808080;">&#93;</span>
<span style="color: #0000FF;">UNION</span> <span style="color: #808080;">ALL</span>
<span style="color: #0000FF;">SELECT</span> <span style="color: #808080;">&#91;</span>c1<span style="color: #808080;">&#93;</span>,<span style="color: #808080;">&#91;</span>c2<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">FROM</span> <span style="color: #808080;">&#91;</span>JDE2<span style="color: #808080;">&#93;</span>.<span style="color: #808080;">&#91;</span>dbo<span style="color: #808080;">&#93;</span>.<span style="color: #808080;">&#91;</span>F42119<span style="color: #808080;">&#93;</span>
&nbsp;
<span style="color: #008080;">--OR</span>
&nbsp;
<span style="color: #0000FF;">SELECT</span> <span style="color: #0000FF;">DISTINCT</span> <span style="color: #808080;">*</span> <span style="color: #0000FF;">FROM</span>
<span style="color: #808080;">&#40;</span>
  <span style="color: #0000FF;">SELECT</span> <span style="color: #808080;">&#91;</span>c1<span style="color: #808080;">&#93;</span>,<span style="color: #808080;">&#91;</span>c2<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">FROM</span> <span style="color: #808080;">&#91;</span>JDE1<span style="color: #808080;">&#93;</span>.<span style="color: #808080;">&#91;</span>dbo<span style="color: #808080;">&#93;</span>.<span style="color: #808080;">&#91;</span>F42119<span style="color: #808080;">&#93;</span>
  <span style="color: #0000FF;">UNION</span> <span style="color: #808080;">ALL</span>
  <span style="color: #0000FF;">SELECT</span> <span style="color: #808080;">&#91;</span>c1<span style="color: #808080;">&#93;</span>,<span style="color: #808080;">&#91;</span>c2<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">FROM</span> <span style="color: #808080;">&#91;</span>JDE2<span style="color: #808080;">&#93;</span>.<span style="color: #808080;">&#91;</span>dbo<span style="color: #808080;">&#93;</span>.<span style="color: #808080;">&#91;</span>F42119<span style="color: #808080;">&#93;</span>
<span style="color: #808080;">&#41;</span></pre></div></div>

<p>And don't get me started on unioning subqueries with GROUP BY's - Why don't you just throw half your processers in the garbage, light tempdb on fire and put all your data in heaps.</p>
]]></content:encoded>
			<wfw:commentRss>http://timlaqua.com/2012/02/uncivil-unions/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Hiding SSRS Schedule Jobs In SSMS</title>
		<link>http://timlaqua.com/2012/01/hiding-ssrs-schedule-jobs-in-ssms/</link>
		<comments>http://timlaqua.com/2012/01/hiding-ssrs-schedule-jobs-in-ssms/#comments</comments>
		<pubDate>Wed, 11 Jan 2012 14:26:16 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Scripts & Code]]></category>
		<category><![CDATA[bi]]></category>
		<category><![CDATA[ssrs]]></category>

		<guid isPermaLink="false">http://timlaqua.com/?p=864</guid>
		<description><![CDATA[Everybody hates these things. If you're in the Activity Monitor or browsing via the SSMS tree view, these GUID jobs that represent SSRS subscriptions are really just none of our concern. Sure, I can admit that I've seen people manually fire these to re-send a given subscription, but you can just do that using the [...]]]></description>
			<content:encoded><![CDATA[<p>Everybody hates these things.  If you're in the Activity Monitor or browsing via the SSMS tree view, these GUID jobs that represent SSRS subscriptions are really just none of our concern.  Sure, I can admit that I've seen people manually fire these to re-send a given subscription, but you can just do that using the AddEvent proc in a query window.  Personally - I don't want to see these... usually...</p>
<p>Connect to the database instance you want to filter the agent jobs out on<br />
Browse to Databases > System Databases > msdb > Programmability > Stored Procedures > System Stored Procedures<br />
Right-click on dbo.sp_help_category and select Modify...</p>
<p>At the top, change the definition of @where_clause to NVARCHAR(MAX)</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>19
</pre></td><td class="code"><pre class="tsql" style="font-family:monospace;">  <span style="color: #0000FF;">DECLARE</span> @where_clause   <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">MAX</span><span style="color: #808080;">&#41;</span></pre></td></tr></table></div>

<p>At the bottom, add in a few lines to append the @where_clause variable with a predicate that filters out the Report Server category when it's you from your workstation (so you can still see that category from another machine if you need to).</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
</pre></td><td class="code"><pre class="tsql" style="font-family:monospace;">  <span style="color: #0000FF;">SELECT</span> @cmd <span style="color: #808080;">=</span> @cmd <span style="color: #808080;">+</span> N<span style="color: #FF0000;">'FROM msdb.dbo.syscategories '</span>
&nbsp;
  <span style="color: #0000FF;">SET</span> @where_clause <span style="color: #808080;">+=</span> N<span style="color: #FF0000;">'
  AND
	CASE
		WHEN 
			name = '</span><span style="color: #FF0000;">'Report Server'</span><span style="color: #FF0000;">' 
			AND (
				SELECT RTRIM(nt_username) + '</span><span style="color: #FF0000;">'|'</span><span style="color: #FF0000;">' + RTRIM(hostname) 
				FROM sys.sysprocesses 
				where spid = @@spid) = '</span><span style="color: #FF0000;">'tlaqua|TIMSLAPTOP'</span><span style="color: #FF0000;">'  THEN 0
		ELSE 1
	END = 1 '</span>
&nbsp;
  <span style="color: #008080;">-- Execute the query</span>
  <span style="color: #0000FF;">EXECUTE</span> <span style="color: #808080;">&#40;</span>@cmd <span style="color: #808080;">+</span> @where_clause <span style="color: #808080;">+</span> N<span style="color: #FF0000;">'ORDER BY category_type, name'</span><span style="color: #808080;">&#41;</span>
&nbsp;
  <span style="color: #0000FF;">RETURN</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">@@ERROR</span><span style="color: #808080;">&#41;</span> <span style="color: #008080;">-- 0 means success</span>
<span style="color: #0000FF;">END</span></pre></td></tr></table></div>

<p>So, what on earth are we doing here?  First, replace my nt_username with yours and replace my hostname with yours.  From my less-than-exhaustive trial and error testing, it seems that when either the SSMS Jobs node is expanded or the Job Activity Monitor fetches jobs, two DB calls are made - one to fetch categories and another to fetch jobs.  I tried filtering out the jobs portion originally and that yielded some errors.  So I'm assuming it's trying to marry the categories and the jobs internally, and it expects there to be jobs for each category the first query returned.  By not returning the Report Server category at all, the resulting merged list of jobs doesn't contain any jobs belonging to that category (logically an INNER JOIN).</p>
<p>Sure, this is a dirty hack, but I don't mind.</p>
<p><strong>Update (2012-01-11)</strong><br />
<em>Here is the predicate for hiding those jobs from ALL SSMS clients:</em></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>96
97
98
99
100
101
102
103
104
105
106
</pre></td><td class="code"><pre class="tsql" style="font-family:monospace;">  <span style="color: #0000FF;">SET</span> @where_clause <span style="color: #808080;">+=</span> N<span style="color: #FF0000;">'
  AND
	CASE
		WHEN 
			name = '</span><span style="color: #FF0000;">'Report Server'</span><span style="color: #FF0000;">' 
			AND (
				SELECT program_name 
				FROM sys.sysprocesses 
				where spid = @@spid) = '</span><span style="color: #FF0000;">'Microsoft SQL Server Management Studio'</span><span style="color: #FF0000;">'  THEN 0
		ELSE 1
	END = 1 '</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://timlaqua.com/2012/01/hiding-ssrs-schedule-jobs-in-ssms/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SSIS, BIDS and 64bit System DSNs: Who&#8217;s on first?</title>
		<link>http://timlaqua.com/2011/11/ssis-bids-and-64bit-system-dsns-whos-on-first/</link>
		<comments>http://timlaqua.com/2011/11/ssis-bids-and-64bit-system-dsns-whos-on-first/#comments</comments>
		<pubDate>Fri, 18 Nov 2011 20:34:37 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Scripts & Code]]></category>
		<category><![CDATA[bi]]></category>
		<category><![CDATA[ssis]]></category>

		<guid isPermaLink="false">http://timlaqua.com/?p=828</guid>
		<description><![CDATA[After an hour or so of changing settings, package configurations, protection levels, passwords, connection strings, etc - you might just still have yourself one of those dreaded red boxes (and a headache). And you thought inserting data using ODBC was easy... You might even have yourself some logging that indicates an error like this: [AS400 [...]]]></description>
			<content:encoded><![CDATA[<p>After an hour or so of changing settings, package configurations, protection levels, passwords, connection strings, etc - you  might just still have yourself one of those dreaded red boxes (and a headache).  And you thought inserting data using ODBC was easy...</p>
<p><a href="http://timlaqua.com/wp-content/uploads/2011/11/Execute-Package-Failed-To-Acquire-Connection.png"><img src="http://timlaqua.com/wp-content/uploads/2011/11/Execute-Package-Failed-To-Acquire-Connection.png" alt="" title="Execute Package - Failed To Acquire Connection" width="774" height="551" class="alignnone size-full wp-image-833" /></a></p>
<p>You might even have yourself some logging that indicates an error like this:<br />
<strong>[AS400 [19]] Error: ADO NET Destination has failed to acquire the connection {43E6AE37-24E8-46F6-8AB0-689DB6531167}. The connection may have been corrupted.</strong></p>
<p>Assuming you are using a System DSN for your connection (this article is based on an ODBC DSN using the iSeries Access ODBC Driver to write to DB2, but it applies to any ODBC driver with 32bit and 64bit versions where a System DSN is used for the connection).</p>
<p>Before going on, you should understand and have checked the <strong>PackageProtectionLevel</strong> property in your package.  To get any connection that requires a password to run in BIDS, you can't use DontSaveSensitive (unless you're using package configurations to enter the password or an explicit connection string).  This is by far the most common reason connections fail to validate - but there's many resources out there already on that situation, so I won't go in to it.</p>
<p>Now that we know it SHOULD work - why doesn't it?  In short, because you don't have a 64-bit version of the System DSN you selected.  What sense does that make?  Let me show you.<br />
<span id="more-828"></span><br />
<a href="http://timlaqua.com/wp-content/uploads/2011/11/ODBC-Administration-Programs.png"><img src="http://timlaqua.com/wp-content/uploads/2011/11/ODBC-Administration-Programs.png" alt="" title="ODBC Administration Programs" width="202" height="71" class="alignnone size-full wp-image-835" /></a></p>
<p>I'm sure you've all seen this before - which one do we select?  I'm apparently pretty random with it as when I started this investigation, I found various different System DSNs in both places (and they didn't match).  Maybe you just use the Control Panel to get to your ODBC Data Sources:</p>
<p><a href="http://timlaqua.com/wp-content/uploads/2011/11/Data-sources-ODBC-Control-Panel.png"><img src="http://timlaqua.com/wp-content/uploads/2011/11/Data-sources-ODBC-Control-Panel.png" alt="" title="Data sources (ODBC) Control Panel" width="234" height="155" class="alignnone size-full wp-image-831" /></a></p>
<p>Interesting - we know there's two places to manage ODBC connections...  Which one is this?  It's the 64bit one.  Which means if this is the only way you enter System DSNs, all you ever enter are 64bit System DSNs.</p>
<p>Now, on to how this happened in the first place.  First, I'll create both a 64bit DSN and a 32bit DSN:<br />
<a href="http://timlaqua.com/wp-content/uploads/2011/11/ODBC-64bit.png"><img src="http://timlaqua.com/wp-content/uploads/2011/11/ODBC-64bit.png" alt="" title="ODBC 64bit" width="471" height="390" class="alignnone size-full wp-image-841" /></a><br />
<a href="http://timlaqua.com/wp-content/uploads/2011/11/ODBC-32bit.png"><img src="http://timlaqua.com/wp-content/uploads/2011/11/ODBC-32bit.png" alt="" title="ODBC 32bit" width="471" height="390" class="alignnone size-full wp-image-842" /></a></p>
<p>Then in SSIS, we create an ODBC connection, the dropdown lists our DSNs for us like so:</p>
<p><a href="http://timlaqua.com/wp-content/uploads/2011/11/ADO-Connection-Manager-ODBC-32bit-DSN.png"><img src="http://timlaqua.com/wp-content/uploads/2011/11/ADO-Connection-Manager-ODBC-32bit-DSN.png" alt="" title="ADO Connection Manager - ODBC - 32bit DSN" width="608" height="623" class="alignnone size-full wp-image-830" /></a></p>
<p>Notice that these are a mismash of both your User DSNs and 32bit System DSNs (and probably File DSNs... but who uses those anyway).  No 64bit DSNs are listed.  As a side note, this also presents itself when you create a "System DSN" (not knowing you're creating a 64bit specific DSN), then you go in to BIDS and can't find your shiny new DSN in the list.  To get your DSN to show, you probably go back in and create a User DSN, and it will then show up.  Until you try to run it on the server under a different username - which can be even more confusing.</p>
<p>To test if you are encountering this 32/64bit DSN issue, you can change your SSIS Solution properties to use the 32bit runtime:</p>
<p><a href="http://timlaqua.com/wp-content/uploads/2011/11/Debugging-Configuration.png"><img src="http://timlaqua.com/wp-content/uploads/2011/11/Debugging-Configuration.png" alt="" title="Debugging Configuration" width="701" height="425" class="alignnone size-full wp-image-832" /></a></p>
<p>Now run your package again and it should look a little more like this:</p>
<p><a href="http://timlaqua.com/wp-content/uploads/2011/11/Execute-Package-Success-32bit.png"><img src="http://timlaqua.com/wp-content/uploads/2011/11/Execute-Package-Success-32bit.png" alt="" title="Execute Package - Success - 32bit" width="774" height="551" class="alignnone size-full wp-image-834" /></a></p>
<p>You can also take your compiled package and run it with the 32bit version of dtexec and the 64bit version.  Here's what that should look like if you're having this issue:</p>
<p><em>Use the dtexec located under <strong>Program Files\Microsoft SQL Server\100\DTS\Binn</strong></em></p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">C:\&gt;&quot;C:\Program Files\Microsoft SQL Server\100\DTS\Binn\dtexec&quot; /FILE &quot;C:\Users\
tlaqua\Documents\Visual Studio 2008\Projects\AS400 ODBC Test\AS400 ODBC Test\bin
\ExportToAS400.dtsx&quot; /CHECKPOINTING OFF  /REPORTING EWCDI
Microsoft (R) SQL Server Execute Package Utility
Version 10.50.2500.0 for 64-bit
Copyright (C) Microsoft Corporation 2010. All rights reserved.
&nbsp;
Started:  12:29:04 PM
Info: 2011-11-18 12:29:04.24
   Code: 0x4004300A
   Source: Export to AS400 SSIS.Pipeline
   Description: Validation phase is beginning.
End Info
Error: 2011-11-18 12:29:05.21
   Code: 0xC0208452
   Source: Export to AS400 AS400 [19]
   Description: ADO NET Destination has failed to acquire the connection {43E6AE
37-24E8-46F6-8AB0-689DB6531167}. The connection may have been corrupted.
End Error
Error: 2011-11-18 12:29:05.21
   Code: 0xC0047017
   Source: Export to AS400 SSIS.Pipeline
   Description: component &quot;AS400&quot; (19) failed validation and returned error code
 0xC0208452.
End Error
Error: 2011-11-18 12:29:05.21
   Code: 0xC004700C
   Source: Export to AS400 SSIS.Pipeline
   Description: One or more component failed validation.
End Error
Error: 2011-11-18 12:29:05.21
   Code: 0xC0024107
   Source: Export to AS400
   Description: There were errors during task validation.
End Error
DTExec: The package execution returned DTSER_FAILURE (1).
Started:  12:29:04 PM
Finished: 12:29:05 PM
Elapsed:  1.029 seconds</pre></div></div>

<p><em>Use the dtexec located under <strong>Program Files<span style="background-color: yellow;"> (x86)</span>\Microsoft SQL Server\100\DTS\Binn</strong></em></p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">C:\&gt;&quot;C:\Program Files (x86)\Microsoft SQL Server\100\DTS\Binn\dtexec&quot; /FILE &quot;C:\
Users\tlaqua\Documents\Visual Studio 2008\Projects\AS400 ODBC Test\AS400 ODBC Te
st\bin\ExportToAS400.dtsx&quot; /CHECKPOINTING OFF  /REPORTING EWCDI
Microsoft (R) SQL Server Execute Package Utility
Version 10.50.2500.0 for 32-bit
Copyright (C) Microsoft Corporation 2010. All rights reserved.
&nbsp;
Started:  12:29:49 PM
Info: 2011-11-18 12:29:49.96
   Code: 0x4004300A
   Source: Export to AS400 SSIS.Pipeline
   Description: Validation phase is beginning.
End Info
Info: 2011-11-18 12:29:51.14
   Code: 0x4004300A
   Source: Export to AS400 SSIS.Pipeline
   Description: Validation phase is beginning.
End Info
Info: 2011-11-18 12:29:51.41
   Code: 0x40043006
   Source: Export to AS400 SSIS.Pipeline
   Description: Prepare for Execute phase is beginning.
End Info
Info: 2011-11-18 12:29:51.58
   Code: 0x40043007
   Source: Export to AS400 SSIS.Pipeline
   Description: Pre-Execute phase is beginning.
End Info
Info: 2011-11-18 12:29:51.94
   Code: 0x4004300C
   Source: Export to AS400 SSIS.Pipeline
   Description: Execute phase is beginning.
End Info
DataFlow: 2011-11-18 12:29:51.94
   Source: Export to AS400
   Component &quot;AS400&quot; (19) will receive 2 rows on input &quot;ADO NET Destination Inpu
t&quot; (22)
End DataFlow
DataFlow: 2011-11-18 12:29:52.11
   Source: Export to AS400
   Component &quot;AS400&quot; (19) was given end of rowset on input &quot;ADO NET Destination
Input&quot; (22)
End DataFlow
DataFlow: 2011-11-18 12:29:52.11
   Source: Export to AS400
   Component &quot;AS400&quot; (19) will receive 0 rows on input &quot;ADO NET Destination Inpu
t&quot; (22)
End DataFlow
Info: 2011-11-18 12:29:52.11
   Code: 0x40043008
   Source: Export to AS400 SSIS.Pipeline
   Description: Post Execute phase is beginning.
End Info
Info: 2011-11-18 12:29:52.14
   Code: 0x4004300B
   Source: Export to AS400 SSIS.Pipeline
   Description: &quot;component &quot;AS400&quot; (19)&quot; wrote 2 rows.
End Info
Info: 2011-11-18 12:29:52.14
   Code: 0x40043009
   Source: Export to AS400 SSIS.Pipeline
   Description: Cleanup phase is beginning.
End Info
DTExec: The package execution returned DTSER_SUCCESS (0).
Started:  12:29:49 PM
Finished: 12:29:52 PM
Elapsed:  2.574 seconds</pre></div></div>

<p>So how do we avoid/fix this?</p>
<ol>
<li>Ensure you setup the EXACT same System DSNs in both 64bit and 32bit on your development machine.
<li>On your server(s), you most likely only need to setup the 64bit DSNs as all they do is execute via dtexec and it probably uses the 64bit dtexec by default.
<li>If you plan on opening BIDS on your server - refer to point 1 for the server as well because if you run BIDS on it, it's a development box.
<li>Avoid User DSNs.  While they are kind of magic (they don't differentiate between the 64bit and 32bit administration tool - there's only ONE list of User DSNs), they are a formula for headaches on shared development machines, packages ran by the sql server agent, or packages run via scheduled task (all depending on what user context you have setup on each engine).
<li>If you can't setup 64bit System DSNs and have to use 32-bit System DSNs, ensure you have your BIDS solution set to use the 32bit runtime, ensure when you run the packages using dtexec, you use the 32bit version, and when you execute the package via SQL Server Agent, configure it for 32bit execution:
<p><a href="http://timlaqua.com/wp-content/uploads/2011/11/SQL-Server-Agent-Package-Execution-Options.png"><img src="http://timlaqua.com/wp-content/uploads/2011/11/SQL-Server-Agent-Package-Execution-Options.png" alt="" title="SQL Server Agent - Package Execution Options" width="493" height="408" class="alignnone size-full wp-image-836" /></a>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://timlaqua.com/2011/11/ssis-bids-and-64bit-system-dsns-whos-on-first/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pattern for Conditionally Sending SSRS Subscriptions</title>
		<link>http://timlaqua.com/2011/10/pattern-for-conditionally-sending-ssrs-subscriptions/</link>
		<comments>http://timlaqua.com/2011/10/pattern-for-conditionally-sending-ssrs-subscriptions/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 20:51:34 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Scripts & Code]]></category>
		<category><![CDATA[Thoughts]]></category>
		<category><![CDATA[bi]]></category>
		<category><![CDATA[ssrs]]></category>

		<guid isPermaLink="false">http://timlaqua.com/?p=768</guid>
		<description><![CDATA[This is a pretty common request - send the report if there's an issue, don't send it if there's not an issue. This is a simple pattern for doing that using Data Driven Subscriptions. Here, we're not using the data driven subscription to dynamically populate recipient and parameter information, we're just using it to suppress [...]]]></description>
			<content:encoded><![CDATA[<p>This is a pretty common request - send the report if there's an issue, don't send it if there's not an issue.  This is a simple pattern for doing that using Data Driven Subscriptions.  Here, we're not using the data driven subscription to dynamically populate recipient and parameter information, we're just using it to suppress the sending of the report if the report has no value.</p>
<p>To do this, we only need one thing - a query that returns one row if the report should be sent and zero rows if the report should not be sent.  Here is an example - Let's say I want to send a report out if a JDE Address Book record with an AT1 of 'DC' has been updated after a certain julian date.</p>
<p>First, write a query to return rows meeting that criteria:<span id="more-768"></span></p>

<div class="wp_syntax"><div class="code"><pre class="tsql" style="font-family:monospace;"><span style="color: #0000FF;">SELECT</span> <span style="color: #808080;">*</span>
<span style="color: #0000FF;">FROM</span> LIB.<span style="color: #202020;">F0101</span>
<span style="color: #0000FF;">WHERE</span> ABAT1 <span style="color: #808080;">=</span> <span style="color: #FF0000;">'DC'</span>
	<span style="color: #808080;">AND</span> ABUPMJ <span style="color: #808080;">&gt;=</span> <span style="color: #000;">111292</span></pre></div></div>

<p>That's great, but it can return multiple rows...  So just select the first record (because all we care about is if we have one or more than one - exactly how many is irrelevant).  We also don't care what the column values are, so just select some arbitrary value.</p>

<div class="wp_syntax"><div class="code"><pre class="tsql" style="font-family:monospace;"><span style="color: #0000FF;">SELECT</span> <span style="color: #0000FF;">TOP</span> <span style="color: #000;">1</span> <span style="color: #000;">1</span> <span style="color: #0000FF;">AS</span> DoStuff
<span style="color: #0000FF;">FROM</span> LIB.<span style="color: #202020;">F0101</span>
<span style="color: #0000FF;">WHERE</span> ABAT1 <span style="color: #808080;">=</span> <span style="color: #FF0000;">'DC'</span>
	<span style="color: #808080;">AND</span> ABUPMJ <span style="color: #808080;">&gt;=</span> <span style="color: #000;">111292</span></pre></div></div>

<p>So now we have what we need in SQL - let me add one final note on this for those DB2 users out there.  DB2 doesn't understand "TOP" so we have to use their syntax, FETCH FIRST (and likewise for MySQL, use LIMIT).</p>

<div class="wp_syntax"><div class="code"><pre class="tsql" style="font-family:monospace;"><span style="color: #0000FF;">SELECT</span> <span style="color: #000;">1</span> <span style="color: #0000FF;">AS</span> DoStuff
<span style="color: #0000FF;">FROM</span> LIB.<span style="color: #202020;">F0101</span>
<span style="color: #0000FF;">WHERE</span> ABAT1 <span style="color: #808080;">=</span> <span style="color: #FF0000;">'DC'</span>
	<span style="color: #808080;">AND</span> ABUPMJ <span style="color: #808080;">&gt;=</span> <span style="color: #000;">111292</span>
<span style="color: #0000FF;">FETCH</span> <span style="color: #0000FF;">FIRST</span> <span style="color: #000;">1</span> <span style="color: #0000FF;">ROWS</span> <span style="color: #0000FF;">ONLY</span></pre></div></div>

<p>Now, you're ready to create your subscription.</p>
<h6>Go in to your report Subscriptions and click on the New Data Driven Subscription button</h6>
<p><a style="padding-left: 3px; border-left: 5px solid #bbbbbb; display: block;" href="http://timlaqua.com/wp-content/uploads/2011/10/DataDrivenSubscriptionButton.png"><img src="http://timlaqua.com/wp-content/uploads/2011/10/DataDrivenSubscriptionButton.png" alt="" title="DataDrivenSubscriptionButton" width="482" height="31" class="alignnone size-full wp-image-771" /></a></p>
<h6>Enter meaningful name and select Shared Data Source</h6>
<p><a style="padding-left: 3px; border-left: 5px solid #bbbbbb; display: block;" href="http://timlaqua.com/wp-content/uploads/2011/10/Step1-GeneralOptions.png"><img src="http://timlaqua.com/wp-content/uploads/2011/10/Step1-GeneralOptions.png" alt="" title="Step1-GeneralOptions" width="660" height="308" class="alignnone size-full wp-image-772" /></a><br />
<em>* If you don't use shared data sources - you should <img src='http://timlaqua.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </em></p>
<h6>Select Shared Data Source</h6>
<p><a style="padding-left: 3px; border-left: 5px solid #bbbbbb; display: block;" href="http://timlaqua.com/wp-content/uploads/2011/10/Step2-DataSource.png"><img src="http://timlaqua.com/wp-content/uploads/2011/10/Step2-DataSource.png" alt="" title="Step2-DataSource" width="491" height="99" class="alignnone size-full wp-image-773" /></a><br />
<em>* I really hope you don't have a shared data source called "local" - this is just an example</em></p>
<h6>Enter query we developed above</h6>
<p><a style="padding-left: 3px; border-left: 5px solid #bbbbbb; display: block;" href="http://timlaqua.com/wp-content/uploads/2011/10/Step3-Query.png"><img src="http://timlaqua.com/wp-content/uploads/2011/10/Step3-Query.png" alt="" title="Step3-Query" width="629" height="530" class="alignnone size-full wp-image-774" /></a></p>
<h6>Enter the usual options - all static values</h6>
<p><a style="padding-left: 3px; border-left: 5px solid #bbbbbb; display: block;" href="http://timlaqua.com/wp-content/uploads/2011/10/Step4-SubscriptionOptions.png"><img src="http://timlaqua.com/wp-content/uploads/2011/10/Step4-SubscriptionOptions.png" alt="" title="Step4-SubscriptionOptions" width="574" height="537" class="alignnone size-full wp-image-775" /></a></p>
<h6>Enter parameters - usually just "Use Default"</h6>
<p><a style="padding-left: 3px; border-left: 5px solid #bbbbbb; display: block;" href="http://timlaqua.com/wp-content/uploads/2011/10/Step5-Parameters.png"><img src="http://timlaqua.com/wp-content/uploads/2011/10/Step5-Parameters.png" alt="" title="Step5-Parameters" width="546" height="210" class="alignnone size-full wp-image-776" /></a><br />
<em>* This is one drawback to the pattern, you have to type in your parameter(s) - no dropdowns here if you're not using the default</em></p>
<h6>Select your schedule type</h6>
<p><a style="padding-left: 3px; border-left: 5px solid #bbbbbb; display: block;" href="http://timlaqua.com/wp-content/uploads/2011/10/Step6-ChooseSchedule.png"><img src="http://timlaqua.com/wp-content/uploads/2011/10/Step6-ChooseSchedule.png" alt="" title="Step6-ChooseSchedule" width="488" height="137" class="alignnone size-full wp-image-777" /></a></p>
<h6>And finally the usual timed schedule options</h6>
<p><a style="padding-left: 3px; border-left: 5px solid #bbbbbb; display: block;" href="http://timlaqua.com/wp-content/uploads/2011/10/Step7-DefineSchedule.png"><img src="http://timlaqua.com/wp-content/uploads/2011/10/Step7-DefineSchedule.png" alt="" title="Step7-DefineSchedule" width="520" height="541" class="alignnone size-full wp-image-778" /></a></p>
<p>The schedule you specify will be both the time when the above query is executed to see if the report should be sent as well as the time the report will be sent out (assuming it should be sent out).  As far as who the report is sent to, 99% of the time this should be a distribution list that can be managed elsewhere.  You don't want to be wading through SSRS to update the list of subscribed users (unless you're the only subscribed user... then go ahead).</p>
]]></content:encoded>
			<wfw:commentRss>http://timlaqua.com/2011/10/pattern-for-conditionally-sending-ssrs-subscriptions/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Consuming an Authenticated JSON Feed with SSIS</title>
		<link>http://timlaqua.com/2011/07/consuming-an-authenticated-json-feed-with-ssis/</link>
		<comments>http://timlaqua.com/2011/07/consuming-an-authenticated-json-feed-with-ssis/#comments</comments>
		<pubDate>Sun, 03 Jul 2011 14:53:55 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Scripts & Code]]></category>
		<category><![CDATA[bi]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[ssis]]></category>

		<guid isPermaLink="false">http://timlaqua.com/?p=656</guid>
		<description><![CDATA[For this post, we'll look in to one option for consuming a JSON data feed from a service provider's API. In my case, the provider is AtTask - a web based project management service. This sort of assignment/request is pretty common as various corners of your organization simply want to use the best tool for [...]]]></description>
			<content:encoded><![CDATA[<p>For this post, we'll look in to one option for consuming a JSON data feed from a service provider's API.  In my case, the provider is <a href="http?://www.attask.com/">AtTask</a> - a web based project management service.  This sort of assignment/request is pretty common as various corners of your organization simply want to use the best tool for the job.  Far too infrequently does anyone really look at things like how it connects to your current systems.  They say things like "we have a well documented API and a strong user community" - yeah, I've heard that a few thousand times.  JSON is neat if you're using JQuery.  It's horrible if you're trying to suck data down in to a SQL Server table.  Which is what we're going to do.</p>
<p>First, we wander over to the <a href="https://community.attask.com/attask-restful-api">AtTask API Documentation</a> and figure out how to authenticate.  Notice that every request needs a sessionID - and that sessionID is created by a request to the login url.  This means we'll have to make at least two requests - one to nab a sessionID and another to actually get the data that we want.<br />
<span id="more-656"></span><br />
First, create a new package and drop down all the basic objects we'll need:</p>
<ol>
<li>OLEDB Connection</li>
<li>SQL Task: BEGIN TRANSACTION</li>
<li>SQL Task: TRUNCATE (truncate target table)</li>
<li>Data Flow: Populate table</li>
<li>SQL Task: COMMIT TRANSACTION</li>
<li>SQL Task: ROLLBACK TRANSACTION (failure predicates from truncate and data flow)</li>
</ol>
<p><em>Suggested Control Flow</em><br />
<a href="http://timlaqua.com/wp-content/uploads/2011/07/ControlFlow_Complete.png"><img src="http://timlaqua.com/wp-content/uploads/2011/07/ControlFlow_Complete.png" alt="" title="ControlFlow_Complete" width="380" height="304" class="alignnone size-full wp-image-685" /></a></p>
<p>Because we're trying to maintain a single transaction through multiple executables, set the <strong>RetainSameConnection </strong>property of your OLEDB connection to True.  You certainly could just TRUNCATE and then run the data flow, I just wanted to avoid having the end user(s) hit an empty table mid-load (the API I was working with was a tad slow at times).</p>
<p>Now that you have the control flow under... control... jump in to the Data flow where the interesting stuff happens.  You'll need at least a Script Component Source and an OLEDB destination.</p>
<p><em>Suggested Data Flow</em><br />
<a href="http://timlaqua.com/wp-content/uploads/2011/07/DataFlow_Complete.png"><img src="http://timlaqua.com/wp-content/uploads/2011/07/DataFlow_Complete.png" alt="" title="DataFlow_Complete" width="148" height="142" class="alignnone size-full wp-image-686" /></a></p>
<p>I created two variables to hold the URLs I needed to both login to the API and make the actual request<br />
<a href="http://timlaqua.com/wp-content/uploads/2011/07/DataFlow_Variables.png"><img src="http://timlaqua.com/wp-content/uploads/2011/07/DataFlow_Variables.png" alt="" title="DataFlow_Variables" width="369" height="62" class="alignnone size-full wp-image-687" /></a></p>
<p>Open up the Script Component Source and add the variables to the component:<br />
<a href="http://timlaqua.com/wp-content/uploads/2011/07/ScriptComponent_ReadOnlyVariables.png"><img src="http://timlaqua.com/wp-content/uploads/2011/07/ScriptComponent_ReadOnlyVariables.png" alt="" title="ScriptComponent_ReadOnlyVariables" width="461" height="50" class="alignnone size-full wp-image-691" /></a></p>
<p>Then configure the output to match what you want to come out of the component:<br />
<a href="http://timlaqua.com/wp-content/uploads/2011/07/ScriptComponent_AddOutputColumns.png"><img src="http://timlaqua.com/wp-content/uploads/2011/07/ScriptComponent_AddOutputColumns.png" alt="" title="ScriptComponent_AddOutputColumns" width="497" height="349" class="alignnone size-full wp-image-690" /></a></p>
<p>Finally, edit the script and switch it to build for the .NET Framework 3.5:<br />
<em>Project Explorer > Properties</em><br />
<a href="http://timlaqua.com/wp-content/uploads/2011/07/ProjectExplorer_Properties.png"><img src="http://timlaqua.com/wp-content/uploads/2011/07/ProjectExplorer_Properties.png" alt="" title="ProjectExplorer_Properties" width="277" height="299" class="alignnone size-full wp-image-689" /></a></p>
<p><em>Select .NET 3.5</em><br />
<a href="http://timlaqua.com/wp-content/uploads/2011/07/SelectDotNetFramework35.png"><img src="http://timlaqua.com/wp-content/uploads/2011/07/SelectDotNetFramework35.png" alt="" title="SelectDotNetFramework35" width="384" height="195" class="alignnone size-full wp-image-692" /></a></p>
<p>Then Add references that we'll need for this script:<br />
<a href="http://timlaqua.com/wp-content/uploads/2011/07/ProjectExplorer_AddReference.png"><img src="http://timlaqua.com/wp-content/uploads/2011/07/ProjectExplorer_AddReference.png" alt="" title="ProjectExplorer_AddReference" width="292" height="173" class="alignnone size-full wp-image-688" /></a></p>
<p>Select Assemblies we'll need (System.Runtime.Serialization and System.ServiceModel.Web)<br />
<a href="http://timlaqua.com/wp-content/uploads/2011/07/AddReference_SelectAssemblies.png"><img src="http://timlaqua.com/wp-content/uploads/2011/07/AddReference_SelectAssemblies.png" alt="" title="AddReference_SelectAssemblies" width="464" height="382" class="alignnone size-full wp-image-684" /></a></p>
<p><strong>Make sure to Save All at this point!  You want to make sure that the changes you made to the project get saved, not just the changes to the main.cs file.</strong></p>
<p>And here's my completed script.  The specifics of how you need to login and what the returned data feeds look like will vary, but the basic flow will likely remain the same.</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">using</span> <span style="color: #008080;">System</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.Data</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">using</span> <span style="color: #008080;">Microsoft.SqlServer.Dts.Pipeline.Wrapper</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">using</span> <span style="color: #008080;">Microsoft.SqlServer.Dts.Runtime.Wrapper</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.Xml</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.Net</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.IO</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.Runtime.Serialization.Json</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.Runtime.Serialization</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.Text.RegularExpressions</span><span style="color: #008000;">;</span>
&nbsp;
<span style="color: #000000;">&#91;</span>Microsoft.<span style="color: #0000FF;">SqlServer</span>.<span style="color: #0000FF;">Dts</span>.<span style="color: #0000FF;">Pipeline</span>.<span style="color: #0000FF;">SSISScriptComponentEntryPointAttribute</span><span style="color: #000000;">&#93;</span>
<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">class</span> ScriptMain <span style="color: #008000;">:</span> UserComponent
<span style="color: #000000;">&#123;</span>
    <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">override</span> <span style="color: #0600FF;">void</span> CreateNewOutputRows<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
        <span style="color: #008080; font-style: italic;">// loginURL should be a url that returns JSON containing a sessionID</span>
        <span style="color: #FF0000;">string</span> loginURL <span style="color: #008000;">=</span> Variables.<span style="color: #0000FF;">loginURL</span><span style="color: #008000;">;</span>
&nbsp;
        <span style="color: #008080; font-style: italic;">// Get the sessionID</span>
        HttpWebRequest request <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span>HttpWebRequest<span style="color: #000000;">&#41;</span>WebRequest.<span style="color: #0000FF;">Create</span><span style="color: #000000;">&#40;</span>loginURL<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
        request.<span style="color: #0000FF;">Timeout</span> <span style="color: #008000;">=</span> <span style="color: #FF0000;">300000</span><span style="color: #008000;">;</span>
        HttpWebResponse response <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span>HttpWebResponse<span style="color: #000000;">&#41;</span>request.<span style="color: #0000FF;">GetResponse</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
        StreamReader reader <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> StreamReader<span style="color: #000000;">&#40;</span>response.<span style="color: #0000FF;">GetResponseStream</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #FF0000;">string</span> json <span style="color: #008000;">=</span> reader.<span style="color: #0000FF;">ReadToEnd</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
        Match m <span style="color: #008000;">=</span> Regex.<span style="color: #0000FF;">Match</span><span style="color: #000000;">&#40;</span>json, <span style="color: #666666;">&quot;<span style="color: #008080; font-weight: bold;">\&quot;</span>sessionID<span style="color: #008080; font-weight: bold;">\&quot;</span>: <span style="color: #008080; font-weight: bold;">\&quot;</span>(.+?)<span style="color: #008080; font-weight: bold;">\&quot;</span>&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #FF0000;">string</span> sessionId <span style="color: #008000;">=</span> m.<span style="color: #0000FF;">Groups</span><span style="color: #000000;">&#91;</span><span style="color: #FF0000;">1</span><span style="color: #000000;">&#93;</span>.<span style="color: #0000FF;">Value</span><span style="color: #008000;">;</span>
&nbsp;
        <span style="color: #008080; font-style: italic;">// Need to support pagination, api has a 2000 item limit per req</span>
        XmlNodeList items<span style="color: #008000;">;</span>
        <span style="color: #FF0000;">int</span> rowsPerPage <span style="color: #008000;">=</span> <span style="color: #FF0000;">1000</span><span style="color: #008000;">;</span>
        <span style="color: #FF0000;">int</span> page <span style="color: #008000;">=</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">;</span>
&nbsp;
        <span style="color: #008080; font-style: italic;">// Loop until we find the last page</span>
        <span style="color: #0600FF;">do</span> <span style="color: #000000;">&#123;</span>
            <span style="color: #008080; font-style: italic;">// The taskURL has 3 tokens:</span>
            <span style="color: #008080; font-style: italic;">// {0} = The first record to return for the page we're requesting</span>
            <span style="color: #008080; font-style: italic;">// {1} = The number of records to request</span>
            <span style="color: #008080; font-style: italic;">// {2} = The sessionID</span>
            <span style="color: #FF0000;">string</span> taskURL <span style="color: #008000;">=</span> <span style="color: #FF0000;">string</span>.<span style="color: #0000FF;">Format</span><span style="color: #000000;">&#40;</span>
                Variables.<span style="color: #0000FF;">taskURL</span>, 
                page <span style="color: #008000;">*</span> rowsPerPage <span style="color: #008000;">+</span> <span style="color: #FF0000;">1</span>, 
                rowsPerPage, 
                sessionId<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            request <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span>HttpWebRequest<span style="color: #000000;">&#41;</span>WebRequest.<span style="color: #0000FF;">Create</span><span style="color: #000000;">&#40;</span>taskURL<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            response <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span>HttpWebResponse<span style="color: #000000;">&#41;</span>request.<span style="color: #0000FF;">GetResponse</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #008080; font-style: italic;">// Toss the JSON response in to XML so we can work with it better</span>
            XmlDocument xd <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> XmlDocument<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            XmlDictionaryReader xr <span style="color: #008000;">=</span> JsonReaderWriterFactory.<span style="color: #0000FF;">CreateJsonReader</span><span style="color: #000000;">&#40;</span>
                response.<span style="color: #0000FF;">GetResponseStream</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>, 
                XmlDictionaryReaderQuotas.<span style="color: #0000FF;">Max</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            xr.<span style="color: #0000FF;">Read</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            xd.<span style="color: #0000FF;">LoadXml</span><span style="color: #000000;">&#40;</span>xr.<span style="color: #0000FF;">ReadOuterXml</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #008080; font-style: italic;">// Put each item returned in to a new Buffer row</span>
            items <span style="color: #008000;">=</span> xd.<span style="color: #0000FF;">DocumentElement</span>.<span style="color: #0000FF;">SelectNodes</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;/root/data/item&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #0600FF;">foreach</span> <span style="color: #000000;">&#40;</span>XmlNode item <span style="color: #0600FF;">in</span> items<span style="color: #000000;">&#41;</span>
            <span style="color: #000000;">&#123;</span>
                TaskDataBuffer.<span style="color: #0000FF;">AddRow</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
                TaskDataBuffer.<span style="color: #0000FF;">ProjectId</span> <span style="color: #008000;">=</span> 
                    item.<span style="color: #0000FF;">SelectSingleNode</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;project/ID&quot;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Value</span><span style="color: #008000;">;</span>
                TaskDataBuffer.<span style="color: #0000FF;">ProjectName</span> <span style="color: #008000;">=</span> 
                    item.<span style="color: #0000FF;">SelectSingleNode</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;project/name&quot;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Value</span><span style="color: #008000;">;</span>
&nbsp;
                <span style="color: #008080; font-style: italic;">// This particular feed allows assignedTo to be empty/null</span>
                <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>item.<span style="color: #0000FF;">SelectSingleNode</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;assignedTo/name&quot;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">!=</span> <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span>
                <span style="color: #000000;">&#123;</span>
                    TaskDataBuffer.<span style="color: #0000FF;">TaskAssignedToName</span> <span style="color: #008000;">=</span> 
                        item.<span style="color: #0000FF;">SelectSingleNode</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;assignedTo/name&quot;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Value</span><span style="color: #008000;">;</span>
                <span style="color: #000000;">&#125;</span>
                <span style="color: #0600FF;">else</span>
                <span style="color: #000000;">&#123;</span>
                    TaskDataBuffer.<span style="color: #0000FF;">TaskAssignedToName_IsNull</span> <span style="color: #008000;">=</span> true<span style="color: #008000;">;</span>
                <span style="color: #000000;">&#125;</span>
&nbsp;
                TaskDataBuffer.<span style="color: #0000FF;">TaskId</span> <span style="color: #008000;">=</span> 
                    item.<span style="color: #0000FF;">SelectSingleNode</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;ID&quot;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Value</span><span style="color: #008000;">;</span>
                TaskDataBuffer.<span style="color: #0000FF;">TaskName</span> <span style="color: #008000;">=</span> 
                    item.<span style="color: #0000FF;">SelectSingleNode</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;name&quot;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Value</span><span style="color: #008000;">;</span>
                TaskDataBuffer.<span style="color: #0000FF;">TaskPlannedCompletionDate</span> <span style="color: #008000;">=</span> 
                    item.<span style="color: #0000FF;">SelectSingleNode</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;plannedCompletionDate&quot;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Value</span><span style="color: #008000;">;</span>
                TaskDataBuffer.<span style="color: #0000FF;">TaskPlannedStartDate</span> <span style="color: #008000;">=</span> 
                    item.<span style="color: #0000FF;">SelectSingleNode</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;plannedStartDate&quot;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Value</span><span style="color: #008000;">;</span>
                TaskDataBuffer.<span style="color: #0000FF;">TaskProgressStatus</span> <span style="color: #008000;">=</span> 
                    item.<span style="color: #0000FF;">SelectSingleNode</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;progressStatus&quot;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Value</span><span style="color: #008000;">;</span>
            <span style="color: #000000;">&#125;</span>
            page<span style="color: #008000;">++;</span>
        <span style="color: #000000;">&#125;</span> <span style="color: #0600FF;">while</span> <span style="color: #000000;">&#40;</span>items.<span style="color: #0000FF;">Count</span> <span style="color: #008000;">==</span> rowsPerPage<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Remember that each API you interface with will have it's own nuances to deal with and the above code is pretty specific for the AtTask API I was working with.  The part I want to point out is after we do all the API busy work, we have that JSON feed in a stream, turn it in to XML, and then access the data using XPath selects.</p>
]]></content:encoded>
			<wfw:commentRss>http://timlaqua.com/2011/07/consuming-an-authenticated-json-feed-with-ssis/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Revisiting Embedded Text Qualifiers and the SSIS Flat File Connection Manager</title>
		<link>http://timlaqua.com/2011/06/revisiting-embedded-text-qualifiers-and-the-ssis-flat-file-connection-manager/</link>
		<comments>http://timlaqua.com/2011/06/revisiting-embedded-text-qualifiers-and-the-ssis-flat-file-connection-manager/#comments</comments>
		<pubDate>Thu, 09 Jun 2011 01:45:42 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Scripts & Code]]></category>
		<category><![CDATA[bi]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[powershell]]></category>
		<category><![CDATA[ssis]]></category>

		<guid isPermaLink="false">http://timlaqua.com/?p=607</guid>
		<description><![CDATA[To quickly summarize the problem at hand, the Flat File Connection Manager doesn't support embedded Text Qualifiers. The reason this is a big issue is because the most commonly used text qualifier is a double quote (&#34;) and that's also a commonly used punctuation mark. That means if you have a CSV to import and [...]]]></description>
			<content:encoded><![CDATA[<p>To quickly summarize the problem at hand, the Flat File Connection Manager doesn't support embedded Text Qualifiers.  The reason this is a big issue is because the most commonly used text qualifier is a double quote (&quot;) and that's also a commonly used punctuation mark.  That means if you have a CSV to import and lines that looks like this:<br />
<code><br />
"one","1","two","2","th""r""ee","3","asdf"<br />
"""left","right""","mid""dle","w"",tf","w,""tf",",""omg","omg"","<br />
</code></p>
<p>You would expect to import</p>
<table>
<tr>
<td>one</td>
<td>1</td>
<td>two</td>
<td>2</td>
<td>th"r"ee</td>
<td>3</td>
<td>asdf</td>
</tr>
<tr>
<td>"left</td>
<td>right"</td>
<td>mid"dle</td>
<td>w",tf</td>
<td>w,"tf</td>
<td>,"omg</td>
<td>omg",</td>
</tr>
</table>
<p>That's not what you get, you get an error.  I've seen a few different approaches to working around this known issue:</p>
<ul>
<li><a href="http://www.andrewdenhertog.com/tips/importing-csv-flat-files-in-ssis-dealing-with-double-quotes">Replacing embedded text qualifiers with some other token - &amp;quot; in this case</a></li>
<li><a href="http://www.ideaexcursion.com/2008/11/12/handling-embedded-text-qualifiers/">Import each file as a single column and parse the row in a script task, handling error rows</a></li>
</ul>
<p>What I'd like to explore in this post is using regular expressions to transform the entire file in to something that can be natively consumed by SSIS.  There are two options for dealing with this:</p>
<ul>
<li>Tokenizing the quotation marks found within the cells</li>
<li>Change the text qualifier</li>
</ul>
<p>I chose to change the text qualifier because SSIS natively supports multiple character text qualifiers.  This will allow me to pick something ridiculous that is incredibly unlikely to appear in the data naturally.  Changing the text qualifier also means we won't have to add any extra transformations as we would if we tokenized the embeded quotation marks (to turn them back in to quotation marks).<br />
<span id="more-607"></span><br />
Let's start out with the file we're importing so we have some text to test against (C:\SSISTextQualifier\Input.csv)</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">&quot;one&quot;,&quot;1&quot;,&quot;two&quot;,&quot;2&quot;,&quot;th&quot;&quot;r&quot;&quot;ee&quot;,&quot;3&quot;,&quot;asdf&quot;
&quot;&quot;&quot;left&quot;,&quot;right&quot;&quot;&quot;,&quot;mid&quot;&quot;dle&quot;,&quot;w&quot;&quot;,tf&quot;,&quot;w,&quot;&quot;tf&quot;,&quot;,&quot;&quot;omg&quot;,&quot;omg&quot;&quot;,&quot;</pre></div></div>

<p>Now let's iron out the regular expression we're going to need.</p>
<p>We'll start out with grabbing a bunch of stuff between two double-quotes<br/><br />
<a href="http://timlaqua.com/wp-content/uploads/2011/06/Regex07.png"><img src="http://timlaqua.com/wp-content/uploads/2011/06/Regex07.png" alt="" title="Regex07" width="620" height="343" class="alignnone size-full wp-image-624" /></a><br />
<br/><br />
Ok, we don't just want a bunch of stuff - we want the stuff between each set of quotation marks - we make the * quantifier lazy with a question mark<br/><br />
<a href="http://timlaqua.com/wp-content/uploads/2011/06/Regex01.png"><img src="http://timlaqua.com/wp-content/uploads/2011/06/Regex01.png" alt="" title="Regex01" width="620" height="315" class="alignnone size-full wp-image-616" /></a><br />
<br/><br />
Better... but that th""r""ee is clearly wrong... we have to stop the final quotation mark from matching properly escaped quotation marks.  We can do that with a negative lookahead:<br/><br />
<a href="http://timlaqua.com/wp-content/uploads/2011/06/Regex12.png"><img src="http://timlaqua.com/wp-content/uploads/2011/06/Regex12.png" alt="" title="Regex12" width="620" height="343" class="alignnone size-full wp-image-677" /></a><br />
<br/><br />
That's different - notice that now properly escaped quotation marks aren't abnormally terminating the column match anymore, now they're just acting like normal characters.  We have to make a special exception for escaped quotation marks.  Those have to essentially count as a single character:<br/><br />
<a href="http://timlaqua.com/wp-content/uploads/2011/06/Regex08.png"><img src="http://timlaqua.com/wp-content/uploads/2011/06/Regex08.png" alt="" title="Regex08" width="620" height="343" class="alignnone size-full wp-image-627" /></a><br />
<br/><br />
Perfect - Now we can replace the text qualifiers with something awesome like |~| since we have matched the column content safely<br/><br />
<a href="http://timlaqua.com/wp-content/uploads/2011/06/Regex05.png"><img src="http://timlaqua.com/wp-content/uploads/2011/06/Regex05.png" alt="" title="Regex05" width="620" height="315" class="alignnone size-full wp-image-621" /></a></p>
<p>Now that we have our regex, we just have to decide how to execute.</p>
<h3>Plan A:  SSIS Script Task</h3>
<p>Create a new package with a single script task in it<br/><br />
<a href="http://timlaqua.com/wp-content/uploads/2011/06/SSIS01.png"><img src="http://timlaqua.com/wp-content/uploads/2011/06/SSIS01.png" alt="" title="SSIS01" width="660" height="418" class="alignnone size-full wp-image-637" /></a></p>
<p>Now edit the script (C#) and add the following up by the existing using statements:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">using</span> <span style="color: #008080;">System.IO</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.RegularExpressions</span><span style="color: #008000;">;</span></pre></div></div>

<p>Modify the Main method to look something like this (depending on your paths):</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">        <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> Main<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
        <span style="color: #000000;">&#123;</span>
            StreamReader sr <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> <span style="color: #000000;">System.<span style="color: #0000FF;">IO</span></span>.<span style="color: #0000FF;">StreamReader</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">@&quot;C:\SSISTextQualifier\Input.csv&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #FF0000;">string</span> allText <span style="color: #008000;">=</span> sr.<span style="color: #0000FF;">ReadToEnd</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            sr.<span style="color: #0000FF;">Close</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            StreamWriter sw <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> StreamWriter<span style="color: #000000;">&#40;</span><span style="color: #666666;">@&quot;C:\SSISTextQualifier\InputCleaned.csv&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            sw.<span style="color: #0000FF;">Write</span><span style="color: #000000;">&#40;</span>
                    Regex.<span style="color: #0000FF;">Replace</span><span style="color: #000000;">&#40;</span>
                        allText, 
                        <span style="color: #666666;">@&quot;&quot;</span><span style="color: #666666;">&quot;((?:&quot;</span><span style="color: #666666;">&quot;&quot;</span><span style="color: #666666;">&quot;|.)*?)&quot;</span><span style="color: #666666;">&quot;(?!&quot;</span><span style="color: #666666;">&quot;)&quot;</span>, 
                        <span style="color: #666666;">@&quot;|~|$1|~|&quot;</span>
                    <span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Replace</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;<span style="color: #008080; font-weight: bold;">\&quot;</span><span style="color: #008080; font-weight: bold;">\&quot;</span>&quot;</span>, <span style="color: #666666;">&quot;<span style="color: #008080; font-weight: bold;">\&quot;</span>&quot;</span><span style="color: #000000;">&#41;</span>
            <span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            sw.<span style="color: #0000FF;">Close</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            Dts.<span style="color: #0000FF;">TaskResult</span> <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span><span style="color: #000000;">&#41;</span>ScriptResults.<span style="color: #0000FF;">Success</span><span style="color: #008000;">;</span>
        <span style="color: #000000;">&#125;</span></pre></div></div>

<p>Then run that task and you will have a new file called C:\SSISTextQualifier\InputCleaned.csv that's text qualified by |~| and the escaped double quotes have been replaced with a single double quote.</p>
<h3>Plan B: Powershell</h3>
<p>Since we often call SSIS packages from the SQL Server Agent, we can easily add a Powershell step right before the SSIS package to copy and cleanse our file.  If that's the route you choose, your powershell step will look something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="powershell" style="font-family:monospace;"><span style="color: #008080; font-weight: bold;">gc</span> C:\SSISTextQualifier\Input.csv <span style="color: pink;">|</span> 
<span style="color: pink;">%</span> <span style="color: #000000;">&#123;</span><span style="color: #800080;"><span style="color: #000080;">$_</span></span> <span style="color: #FF0000;">-replace</span> <span style="color: #800000;">&quot;<span style="color: #008080; font-weight: bold;">`&quot;</span>((?:<span style="color: #008080; font-weight: bold;">`&quot;</span><span style="color: #008080; font-weight: bold;">`&quot;</span>|.)*?)<span style="color: #008080; font-weight: bold;">`&quot;</span>(?!<span style="color: #008080; font-weight: bold;">`&quot;</span>)&quot;</span><span style="color: pink;">,</span> <span style="color: #800000;">&quot;|~|<span style="color: #008080; font-weight: bold;">`$</span>1|~|&quot;</span> <span style="color: #FF0000;">-replace</span> <span style="color: #800000;">&quot;<span style="color: #008080; font-weight: bold;">`&quot;</span><span style="color: #008080; font-weight: bold;">`&quot;</span>&quot;</span><span style="color: pink;">,</span> <span style="color: #800000;">&quot;<span style="color: #008080; font-weight: bold;">`&quot;</span>&quot;</span><span style="color: #000000;">&#125;</span> <span style="color: pink;">|</span> 
<span style="color: #008080; font-weight: bold;">sc</span> C:\SSISTextQualifier\InputCleaned2.csv</pre></div></div>

<h3>Final Steps</h3>
<p>However you got your data in to a new file (<strong>C:\SSISTextQualifier\InputCleaned.csv</strong> in my case) with a new text qualifier, you still have to then import the file.  This is done using our old friend the Flat File Connection Manager with the source being the newly minted clean file and with our new text qualifier set as |~|</p>
<p><a href="http://timlaqua.com/wp-content/uploads/2011/06/SSIS02.png"><img src="http://timlaqua.com/wp-content/uploads/2011/06/SSIS02.png" alt="" title="SSIS02" width="550" height="562" class="alignnone size-full wp-image-642" /></a></p>
<p>And that's pretty much it:<br/><br />
<a href="http://timlaqua.com/wp-content/uploads/2011/06/SSIS03.png"><img src="http://timlaqua.com/wp-content/uploads/2011/06/SSIS03.png" alt="" title="SSIS03" width="550" height="562" class="alignnone size-full wp-image-643" /></a></p>
<h3>Conclusion</h3>
<p>Personally, I think the Powershell plan is the cleanest and easiest to implement.  The code isn't hidden away in a script task, and it looks cool.  Doing it this way allows us to kind of abstract this "file fixing" from the SSIS data flows and let them do what they do best.</p>
]]></content:encoded>
			<wfw:commentRss>http://timlaqua.com/2011/06/revisiting-embedded-text-qualifiers-and-the-ssis-flat-file-connection-manager/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reporting Services Source Control 1.0</title>
		<link>http://timlaqua.com/2011/04/reporting-services-source-control-1-0/</link>
		<comments>http://timlaqua.com/2011/04/reporting-services-source-control-1-0/#comments</comments>
		<pubDate>Wed, 20 Apr 2011 11:30:50 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Scripts & Code]]></category>
		<category><![CDATA[bi]]></category>
		<category><![CDATA[ssrs]]></category>
		<category><![CDATA[svn]]></category>

		<guid isPermaLink="false">http://timlaqua.com/?p=503</guid>
		<description><![CDATA[Reporting Services Source Control is an application to create copies of all the reports stored in your Report Manager and commit them to source control (SVN is the only supported source control in the 1.0 release). The need for this arises for two reasons: First, we empower our users to create reports using Report Builder [...]]]></description>
			<content:encoded><![CDATA[<p>Reporting Services Source Control is an application to create copies of all the reports stored in your Report Manager and commit them to source control (SVN is the only supported source control in the 1.0 release).  The need for this arises for two reasons:</p>
<ul>
<li>First, we empower our users to create reports using Report Builder and those reports usually only exist the ReportServer database.  </li>
<li>Second, Report Builder has matured so well that it is no longer very beneficial to create a Report Server project using Business Intelligence Development Studio (BIDS).</li>
</ul>
<p>So now we have intellectual property generated by both end users and developers sitting in Report Manager with no version control whatsoever.  Reporting Services Source Control addresses this by scripting out reports, subscriptions, and other properties and committing them to source control.<span id="more-503"></span></p>
<p>The application and source code is available on Codeplex: <a href="http://rssc.codeplex.com/">Reporting Services Source Control</a></p>
]]></content:encoded>
			<wfw:commentRss>http://timlaqua.com/2011/04/reporting-services-source-control-1-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Monitoring Failed Report Server Subscriptions</title>
		<link>http://timlaqua.com/2011/04/monitoring-failed-report-server-subscriptions/</link>
		<comments>http://timlaqua.com/2011/04/monitoring-failed-report-server-subscriptions/#comments</comments>
		<pubDate>Tue, 19 Apr 2011 11:30:51 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Scripts & Code]]></category>
		<category><![CDATA[bi]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[ssrs]]></category>

		<guid isPermaLink="false">http://timlaqua.com/?p=465</guid>
		<description><![CDATA[While we love to empower our users as much as possible, we still need to pay attention to them and what they're up to. The first place I usually see users running amok as Microsoft BI adoption grows in organization is the Report Subscriptions in SSRS. They go nuts with them. I was at one [...]]]></description>
			<content:encoded><![CDATA[<p>While we love to empower our users as much as possible, we still need to pay attention to them and what they're up to.  The first place I usually see users running amok as Microsoft BI adoption grows in organization is the Report Subscriptions in SSRS.  They go nuts with them.  I was at one company where 50% of the report subscriptions went to users outside of the company - that means our customers were depending on these subscriptions!  Which brings up an interesting licensing debacle...  but that's another story.  Needless to say, when people set up a subscription, they expect it to work.  If it doesn't, we REALLY need to let someone know.</p>
<p>Here, we have a procedure to monitor for Reporting Services subscription failures.  Specifically, email subscription failures.  When a failed subscription is detected, an email is sent to both the subscription owner and a digest of failures is sent to the specified admin group.<span id="more-465"></span></p>
<p>This procedure has saved me so many times it's not even funny.  The last thing you want is your end users knowing about a failure before you.</p>

<div class="wp_syntax"><div class="code"><pre class="tsql" style="font-family:monospace;"><span style="color: #008080;">/************************************************************************
***
*** Procedure:       Alert_FailedReportingServicesSubscriptions
*** Purpose:         Notifies administrators and subscription owners that
***                  subscriptions were not delivered as expected
***      
*** Author:          tl
*** Date Created:    2009-10-28
*** 
*** Revision History
*** Date        Author   Description
*** 2009-10-28  tl       Created
*** 
************************************************************************/</span>
<span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">PROCEDURE</span> <span style="color: #808080;">&#91;</span>dbo<span style="color: #808080;">&#93;</span>.<span style="color: #808080;">&#91;</span>Alert_FailedReportingServicesSubscriptions<span style="color: #808080;">&#93;</span>
   @ReportServerBaseURL <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1024</span><span style="color: #808080;">&#41;</span>
  ,@AdminEmail <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span>
  ,@FromAddress <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span>
  ,@MailDomain <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span>
  ,@NTDomain <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span>
  ,@ReportServerDatabase <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'ReportServer'</span>
  ,@ReportServerSchema <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'dbo'</span>
  ,@HoursToCheck <span style="color: #0000FF;">INT</span> <span style="color: #808080;">=</span> <span style="color: #000;">1</span>
  ,@HourSchedule <span style="color: #0000FF;">INT</span> <span style="color: #808080;">=</span> <span style="color: #000;">16777215</span>
<span style="color: #0000FF;">AS</span>
<span style="color: #0000FF;">BEGIN</span>
  <span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">NOCOUNT</span> <span style="color: #0000FF;">ON</span>;
&nbsp;
  <span style="color: #0000FF;">IF</span> @HourSchedule <span style="color: #808080;">&amp;</span> <span style="color: #FF00FF;">POWER</span><span style="color: #808080;">&#40;</span><span style="color: #000;">2</span>, <span style="color: #FF00FF;">DATEPART</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">HOUR</span>, <span style="color: #FF00FF;">GETDATE</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">&gt;</span> <span style="color: #000;">0</span>
  <span style="color: #0000FF;">BEGIN</span>
    <span style="color: #0000FF;">DECLARE</span> @ReportTableOpen <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">MAX</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">=</span>
    <span style="color: #FF0000;">'&lt;style&gt;
    table { font-family: Calibri, Verdana, Ariel, sans-serif;  font-size: 90%; }
    th { padding-left: 3pt; font-style: italic; text-align: left; border-bottom: 1px solid black;}
    td { padding-left: 3pt; white-space: nowrap; }
    p { font-family: Calibri, Verdana, Ariel, sans-serif;  font-size: 95%; text-indent: 0pt; margin-bottom: 12pt; }
    &lt;/style&gt;
    &lt;p&gt;The following subscription(s) that you created was/were not sent to specified recipients at the date/time you scheduled.  Database Administrators has been notified.  Please reply to this email if you have any questions.&lt;/p&gt;
    &lt;table&gt;
    &lt;tr&gt;&lt;th&gt;Owner&lt;/th&gt;&lt;th&gt;Report&lt;/th&gt;&lt;th&gt;Last Run&lt;/th&gt;&lt;th&gt;Intended Recipients&lt;/th&gt;&lt;th&gt;Status&lt;/th&gt;&lt;/tr&gt;'</span>
&nbsp;
    <span style="color: #0000FF;">DECLARE</span> @ReportTableClose <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">MAX</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'&lt;/table&gt;'</span>
&nbsp;
    <span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">TABLE</span> #FailedReport
      <span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>Id<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">INT</span> <span style="color: #0000FF;">IDENTITY</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1</span>,<span style="color: #000;">1</span><span style="color: #808080;">&#41;</span>
      ,<span style="color: #808080;">&#91;</span>Name<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span>
      ,<span style="color: #808080;">&#91;</span>Link<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">2048</span><span style="color: #808080;">&#41;</span>
      ,<span style="color: #808080;">&#91;</span>LastRunTime<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">DATETIME</span>
      ,<span style="color: #808080;">&#91;</span>OwnerUsername<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span>
      ,<span style="color: #808080;">&#91;</span>IntendedRecipients<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1024</span><span style="color: #808080;">&#41;</span>
      ,<span style="color: #808080;">&#91;</span>Message<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1024</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #0000FF;">DECLARE</span> @<span style="color: #0000FF;">SQL</span> <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">MAX</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'
    INSERT INTO #FailedReport
      ([Name]
      ,[Link]
      ,[LastRunTime]
      ,[OwnerUsername]
      ,[IntendedRecipients]
      ,[Message])
    SELECT
       b.Name
      ,'</span><span style="color: #FF0000;">'&lt;a href=&quot;'</span> <span style="color: #808080;">+</span> @ReportServerBaseURL <span style="color: #808080;">+</span> <span style="color: #FF0000;">''</span><span style="color: #FF0000;">' + b.Path + '</span><span style="color: #FF0000;">'&quot;&gt;'</span><span style="color: #FF0000;">' + b.Name + '</span><span style="color: #FF0000;">'&lt;/a&gt;'</span><span style="color: #FF0000;">' AS [Link]
      ,LastRunTime 
      ,REPLACE(c.UserName, '</span><span style="color: #FF0000;">''</span> <span style="color: #808080;">+</span> @NTDomain <span style="color: #808080;">+</span> <span style="color: #0000FF;">CHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">92</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">''</span><span style="color: #FF0000;">', '</span><span style="color: #FF0000;">''</span><span style="color: #FF0000;">') AS [OwnerUserName]
      ,REPLACE(CAST(ExtensionSettings AS XML).value
        ('</span><span style="color: #FF0000;">'(//ParameterValue[Name=&quot;TO&quot;]/Value)[1]'</span><span style="color: #FF0000;">'
        ,'</span><span style="color: #FF0000;">'VARCHAR(1024)'</span><span style="color: #FF0000;">')
      + '</span><span style="color: #FF0000;">';'</span><span style="color: #FF0000;">' 
      + ISNULL(CAST(ExtensionSettings AS XML).value
        ('</span><span style="color: #FF0000;">'(//ParameterValue[Name=&quot;CC&quot;]/Value)[1]'</span><span style="color: #FF0000;">'
        ,'</span><span style="color: #FF0000;">'VARCHAR(1024)'</span><span style="color: #FF0000;">'), '</span><span style="color: #FF0000;">''</span><span style="color: #FF0000;">'),'</span><span style="color: #FF0000;">';;'</span><span style="color: #FF0000;">','</span><span style="color: #FF0000;">';'</span><span style="color: #FF0000;">') AS [IntendedRecipients]
      ,LEFT(ISNULL(LastStatus, '</span><span style="color: #FF0000;">''</span><span style="color: #FF0000;">'), 1024) AS [Message]
    FROM '</span> <span style="color: #808080;">+</span> @ReportServerDatabase <span style="color: #808080;">+</span> <span style="color: #FF0000;">'.'</span> <span style="color: #808080;">+</span> @ReportServerSchema <span style="color: #808080;">+</span> <span style="color: #FF0000;">'.Subscriptions a
      INNER JOIN '</span> <span style="color: #808080;">+</span> @ReportServerDatabase <span style="color: #808080;">+</span> <span style="color: #FF0000;">'.'</span> <span style="color: #808080;">+</span> @ReportServerSchema <span style="color: #808080;">+</span> <span style="color: #FF0000;">'.Catalog b WITH(NOLOCK) 
        ON a.Report_OID=b.ItemId
      INNER JOIN '</span> <span style="color: #808080;">+</span> @ReportServerDatabase <span style="color: #808080;">+</span> <span style="color: #FF0000;">'.'</span> <span style="color: #808080;">+</span> @ReportServerSchema <span style="color: #808080;">+</span> <span style="color: #FF0000;">'.Users c WITH(NOLOCK)
        ON a.OwnerID = c.UserID
    WHERE 
      a.DeliveryExtension = '</span><span style="color: #FF0000;">'Report Server Email'</span><span style="color: #FF0000;">'
      AND LastStatus NOT LIKE '</span><span style="color: #FF0000;">'Mail Sent%'</span><span style="color: #FF0000;">' 
      AND LastStatus NOT LIKE '</span><span style="color: #FF0000;">'% 0 errors.'</span><span style="color: #FF0000;">'
      AND LastStatus NOT LIKE '</span><span style="color: #FF0000;">'New Sub%'</span><span style="color: #FF0000;">'
      AND LastStatus NOT LIKE '</span><span style="color: #FF0000;">'Pending%'</span><span style="color: #FF0000;">'
      AND LastRunTime &gt;= DATEADD(HOUR, -1 * '</span> <span style="color: #808080;">+</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>@HoursToCheck <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">10</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">', GETDATE())
    ORDER BY REPLACE(c.UserName, '</span><span style="color: #FF0000;">''</span> <span style="color: #808080;">+</span> @NTDomain <span style="color: #808080;">+</span> <span style="color: #0000FF;">CHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">92</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">''</span><span style="color: #FF0000;">', '</span><span style="color: #FF0000;">''</span><span style="color: #FF0000;">'), b.Name'</span>
&nbsp;
    <span style="color: #0000FF;">EXECUTE</span><span style="color: #808080;">&#40;</span>@<span style="color: #0000FF;">SQL</span><span style="color: #808080;">&#41;</span>
&nbsp;
    <span style="color: #0000FF;">IF</span> <span style="color: #808080;">&#40;</span><span style="color: #0000FF;">SELECT</span> <span style="color: #FF00FF;">COUNT</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">FROM</span> #FailedReport<span style="color: #808080;">&#41;</span> <span style="color: #808080;">&gt;</span> <span style="color: #000;">0</span>
    <span style="color: #0000FF;">BEGIN</span>
      <span style="color: #0000FF;">DECLARE</span> 
         @FullReportTable <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">MAX</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">''</span>
        ,@LastOwnerId <span style="color: #0000FF;">INT</span> <span style="color: #808080;">=</span> <span style="color: #000;">0</span>
        ,@Username <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span>
&nbsp;
      <span style="color: #0000FF;">DECLARE</span> @Owner <span style="color: #0000FF;">TABLE</span>
          <span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>OwnerId<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">INT</span> <span style="color: #0000FF;">IDENTITY</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1</span>,<span style="color: #000;">1</span><span style="color: #808080;">&#41;</span>
          ,<span style="color: #808080;">&#91;</span>Username<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>
&nbsp;
      <span style="color: #0000FF;">DECLARE</span> @Notification <span style="color: #0000FF;">TABLE</span>
        <span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>NotificationId<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">INT</span> <span style="color: #0000FF;">IDENTITY</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1</span>,<span style="color: #000;">1</span><span style="color: #808080;">&#41;</span>
        ,<span style="color: #808080;">&#91;</span><span style="color: #0000FF;">TO</span><span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span>
        ,<span style="color: #808080;">&#91;</span>Body<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">MAX</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>
&nbsp;
      <span style="color: #0000FF;">INSERT</span> <span style="color: #0000FF;">INTO</span> @Owner
        <span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>Username<span style="color: #808080;">&#93;</span><span style="color: #808080;">&#41;</span>
      <span style="color: #0000FF;">SELECT</span> <span style="color: #0000FF;">DISTINCT</span> OwnerUsername
      <span style="color: #0000FF;">FROM</span> #FailedReport
      <span style="color: #0000FF;">ORDER</span> <span style="color: #0000FF;">BY</span> OwnerUsername
&nbsp;
      <span style="color: #0000FF;">DECLARE</span> @UserFailedReport <span style="color: #0000FF;">TABLE</span>
        <span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>Id<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">INT</span> <span style="color: #0000FF;">IDENTITY</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1</span>,<span style="color: #000;">1</span><span style="color: #808080;">&#41;</span>
        ,<span style="color: #808080;">&#91;</span>Name<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span>
        ,<span style="color: #808080;">&#91;</span>Link<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">2048</span><span style="color: #808080;">&#41;</span>
        ,<span style="color: #808080;">&#91;</span>LastRunTime<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">DATETIME</span>
        ,<span style="color: #808080;">&#91;</span>OwnerUsername<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span>
        ,<span style="color: #808080;">&#91;</span>IntendedRecipients<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1024</span><span style="color: #808080;">&#41;</span>
        ,<span style="color: #808080;">&#91;</span>Message<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1024</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>
&nbsp;
      <span style="color: #0000FF;">WHILE</span> <span style="color: #808080;">EXISTS</span> <span style="color: #808080;">&#40;</span><span style="color: #0000FF;">SELECT</span> <span style="color: #0000FF;">TOP</span> <span style="color: #000;">1</span> <span style="color: #000;">1</span> <span style="color: #0000FF;">FROM</span> @Owner <span style="color: #0000FF;">WHERE</span> <span style="color: #808080;">&#91;</span>OwnerId<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&gt;</span> @LastOwnerId<span style="color: #808080;">&#41;</span>
      <span style="color: #0000FF;">BEGIN</span>
        <span style="color: #0000FF;">DELETE</span> <span style="color: #0000FF;">FROM</span> @UserFailedReport
&nbsp;
        <span style="color: #0000FF;">SELECT</span> <span style="color: #0000FF;">TOP</span> <span style="color: #000;">1</span> 
           @Username <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>Username<span style="color: #808080;">&#93;</span>
          ,@LastOwnerId <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>OwnerId<span style="color: #808080;">&#93;</span>
        <span style="color: #0000FF;">FROM</span> @Owner 
        <span style="color: #0000FF;">WHERE</span> <span style="color: #808080;">&#91;</span>OwnerId<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&gt;</span> @LastOwnerId
        <span style="color: #0000FF;">ORDER</span> <span style="color: #0000FF;">BY</span> <span style="color: #808080;">&#91;</span>OwnerId<span style="color: #808080;">&#93;</span>
&nbsp;
        <span style="color: #0000FF;">DECLARE</span> 
           @UserReportTable <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">MAX</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">''</span>
          ,@LastId <span style="color: #0000FF;">INT</span> <span style="color: #808080;">=</span> <span style="color: #000;">0</span>
&nbsp;
        <span style="color: #0000FF;">INSERT</span> <span style="color: #0000FF;">INTO</span> @UserFailedReport
          <span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>Name<span style="color: #808080;">&#93;</span>
          ,<span style="color: #808080;">&#91;</span>Link<span style="color: #808080;">&#93;</span>
          ,<span style="color: #808080;">&#91;</span>LastRunTime<span style="color: #808080;">&#93;</span>
          ,<span style="color: #808080;">&#91;</span>OwnerUsername<span style="color: #808080;">&#93;</span>
          ,<span style="color: #808080;">&#91;</span>IntendedRecipients<span style="color: #808080;">&#93;</span>
          ,<span style="color: #808080;">&#91;</span>Message<span style="color: #808080;">&#93;</span><span style="color: #808080;">&#41;</span>
        <span style="color: #0000FF;">SELECT</span>
           <span style="color: #808080;">&#91;</span>Name<span style="color: #808080;">&#93;</span>
          ,<span style="color: #808080;">&#91;</span>Link<span style="color: #808080;">&#93;</span>
          ,<span style="color: #808080;">&#91;</span>LastRunTime<span style="color: #808080;">&#93;</span>
          ,<span style="color: #808080;">&#91;</span>OwnerUserName<span style="color: #808080;">&#93;</span>
          ,<span style="color: #808080;">&#91;</span>IntendedRecipients<span style="color: #808080;">&#93;</span>
          ,<span style="color: #808080;">&#91;</span>Message<span style="color: #808080;">&#93;</span>
        <span style="color: #0000FF;">FROM</span> #FailedReport
        <span style="color: #0000FF;">WHERE</span> <span style="color: #808080;">&#91;</span>OwnerUsername<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> @Username
&nbsp;
        <span style="color: #0000FF;">WHILE</span> <span style="color: #808080;">EXISTS</span> <span style="color: #808080;">&#40;</span><span style="color: #0000FF;">SELECT</span> <span style="color: #0000FF;">TOP</span> <span style="color: #000;">1</span> <span style="color: #000;">1</span> <span style="color: #0000FF;">FROM</span> @UserFailedReport <span style="color: #0000FF;">WHERE</span> <span style="color: #808080;">&#91;</span>Id<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&gt;</span> @LastId<span style="color: #808080;">&#41;</span>
        <span style="color: #0000FF;">BEGIN</span>
&nbsp;
          <span style="color: #0000FF;">SELECT</span> <span style="color: #0000FF;">TOP</span> <span style="color: #000;">1</span>
             @UserReportTable <span style="color: #808080;">+=</span> <span style="color: #FF0000;">'&lt;tr&gt;&lt;td&gt;'</span> <span style="color: #808080;">+</span> IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'&lt;a href=&quot;mailto:'</span> <span style="color: #808080;">+</span> <span style="color: #808080;">&#91;</span>OwnerUsername<span style="color: #808080;">&#93;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'@'</span> <span style="color: #808080;">+</span> @MailDomain <span style="color: #808080;">+</span> <span style="color: #FF0000;">'&quot;&gt;'</span> <span style="color: #808080;">+</span> <span style="color: #808080;">&#91;</span>OwnerUsername<span style="color: #808080;">&#93;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'&lt;/a&gt;'</span>, <span style="color: #FF0000;">'Unknown'</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'&lt;/td&gt;&lt;td&gt;'</span> <span style="color: #808080;">+</span> IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>Link<span style="color: #808080;">&#93;</span>, <span style="color: #FF0000;">'Unavailable'</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'&lt;/td&gt;&lt;td&gt;'</span> <span style="color: #808080;">+</span> IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">VARCHAR</span>, <span style="color: #808080;">&#91;</span>LastRunTime<span style="color: #808080;">&#93;</span>, <span style="color: #000;">120</span><span style="color: #808080;">&#41;</span>, <span style="color: #FF0000;">'Never'</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'&lt;/td&gt;&lt;td&gt;'</span> <span style="color: #808080;">+</span> IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>IntendedRecipients<span style="color: #808080;">&#93;</span>, <span style="color: #FF0000;">'Unknown'</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'&lt;/td&gt;&lt;td&gt;'</span> <span style="color: #808080;">+</span> IS<span style="color: #808080;">NULL</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>Message<span style="color: #808080;">&#93;</span>,<span style="color: #FF0000;">'Unknown'</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'&lt;/td&gt;&lt;/tr&gt;'</span> <span style="color: #808080;">+</span> <span style="color: #0000FF;">CHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">13</span><span style="color: #808080;">&#41;</span>
            ,@LastId <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>Id<span style="color: #808080;">&#93;</span>
          <span style="color: #0000FF;">FROM</span> @UserFailedReport
          <span style="color: #0000FF;">WHERE</span> <span style="color: #808080;">&#91;</span>Id<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&gt;</span> @LastId
          <span style="color: #0000FF;">ORDER</span> <span style="color: #0000FF;">BY</span> <span style="color: #808080;">&#91;</span>Id<span style="color: #808080;">&#93;</span>
        <span style="color: #0000FF;">END</span>
&nbsp;
        <span style="color: #0000FF;">SET</span> @FullReportTable <span style="color: #808080;">+=</span> @UserReportTable <span style="color: #808080;">+</span> <span style="color: #0000FF;">CHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">13</span><span style="color: #808080;">&#41;</span>
&nbsp;
        <span style="color: #0000FF;">SET</span> @UserReportTable <span style="color: #808080;">=</span> @ReportTableOpen <span style="color: #808080;">+</span> @UserReportTable <span style="color: #808080;">+</span> @ReportTableClose
&nbsp;
        <span style="color: #0000FF;">INSERT</span> <span style="color: #0000FF;">INTO</span> @Notification <span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span><span style="color: #0000FF;">TO</span><span style="color: #808080;">&#93;</span>, <span style="color: #808080;">&#91;</span>Body<span style="color: #808080;">&#93;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">VALUES</span> <span style="color: #808080;">&#40;</span>@Username <span style="color: #808080;">+</span> <span style="color: #FF0000;">'@'</span> <span style="color: #808080;">+</span> @MailDomain, @UserReportTable<span style="color: #808080;">&#41;</span>
      <span style="color: #0000FF;">END</span>
&nbsp;
&nbsp;
      <span style="color: #0000FF;">SET</span> @FullReportTable <span style="color: #808080;">=</span> @ReportTableOpen <span style="color: #808080;">+</span> @FullReportTable <span style="color: #808080;">+</span> @ReportTableClose
&nbsp;
      <span style="color: #0000FF;">INSERT</span> <span style="color: #0000FF;">INTO</span> @Notification <span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span><span style="color: #0000FF;">TO</span><span style="color: #808080;">&#93;</span>, <span style="color: #808080;">&#91;</span>Body<span style="color: #808080;">&#93;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">VALUES</span> <span style="color: #808080;">&#40;</span>@AdminEmail, @FullReportTable<span style="color: #808080;">&#41;</span>
&nbsp;
      <span style="color: #0000FF;">DECLARE</span> 
         @LastNotificationId <span style="color: #0000FF;">INT</span> <span style="color: #808080;">=</span> <span style="color: #000;">0</span>
        ,@<span style="color: #0000FF;">TO</span> <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">255</span><span style="color: #808080;">&#41;</span>
        ,@Body <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">MAX</span><span style="color: #808080;">&#41;</span>
&nbsp;
      <span style="color: #0000FF;">WHILE</span> <span style="color: #808080;">EXISTS</span> <span style="color: #808080;">&#40;</span><span style="color: #0000FF;">SELECT</span> <span style="color: #0000FF;">TOP</span> <span style="color: #000;">1</span> <span style="color: #000;">1</span> <span style="color: #0000FF;">FROM</span> @Notification <span style="color: #0000FF;">WHERE</span> <span style="color: #808080;">&#91;</span>NotificationId<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&gt;</span> @LastNotificationId<span style="color: #808080;">&#41;</span>
      <span style="color: #0000FF;">BEGIN</span>
&nbsp;
        <span style="color: #0000FF;">SELECT</span> <span style="color: #0000FF;">TOP</span> <span style="color: #000;">1</span> 
           @<span style="color: #0000FF;">TO</span> <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span><span style="color: #0000FF;">TO</span><span style="color: #808080;">&#93;</span>
          ,@Body <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>Body<span style="color: #808080;">&#93;</span>
          ,@LastNotificationId <span style="color: #808080;">=</span> <span style="color: #808080;">&#91;</span>NotificationId<span style="color: #808080;">&#93;</span>
        <span style="color: #0000FF;">FROM</span> @Notification
        <span style="color: #0000FF;">WHERE</span> <span style="color: #808080;">&#91;</span>NotificationId<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&gt;</span> @LastNotificationId
        <span style="color: #0000FF;">ORDER</span> <span style="color: #0000FF;">BY</span> <span style="color: #808080;">&#91;</span>NotificationId<span style="color: #808080;">&#93;</span>
&nbsp;
        <span style="color: #0000FF;">EXEC</span> msdb.<span style="color: #202020;">dbo</span>.<span style="color: #202020;">sp_send_dbmail</span>
           @recipients <span style="color: #808080;">=</span> @<span style="color: #0000FF;">TO</span>
          ,@from_address <span style="color: #808080;">=</span> @FromAddress
          ,@subject <span style="color: #808080;">=</span> <span style="color: #FF0000;">'Failed Report Manager Subscription(s)'</span>
          ,@body <span style="color: #808080;">=</span> @Body
          ,@importance <span style="color: #808080;">=</span> <span style="color: #FF0000;">'High'</span>
          ,@body_format <span style="color: #808080;">=</span> <span style="color: #FF0000;">'HTML'</span>  
&nbsp;
        <span style="color: #008080;">--DECLARE @ProcName VARCHAR(255) = OBJECT_NAME(@@PROCID)</span>
&nbsp;
        <span style="color: #008080;">--EXEC [dbo].[Utility_Alert_SendMail] </span>
        <span style="color: #008080;">--   @AlertSubject = 'Failed Report Manager Subscription(s)'</span>
        <span style="color: #008080;">--  ,@AlertRecipients = @To</span>
        <span style="color: #008080;">--  ,@AlertBody = @Body</span>
        <span style="color: #008080;">--  ,@AlertFormat = 'HTML'</span>
        <span style="color: #008080;">--  ,@AlertSource = @ProcName</span>
        <span style="color: #008080;">--  ,@FromAddress = @FromAddress</span>
&nbsp;
      <span style="color: #0000FF;">END</span>
    <span style="color: #0000FF;">END</span>
&nbsp;
    <span style="color: #0000FF;">DROP</span> <span style="color: #0000FF;">TABLE</span> #FailedReport
  <span style="color: #0000FF;">END</span>
<span style="color: #0000FF;">END</span></pre></div></div>

<p>Now to run it:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">EXEC <span style="color: #66cc66;">&#91;</span>Alert_FailedReportingServicesSubscriptions<span style="color: #66cc66;">&#93;</span> 
   @ReportServerBaseURL <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'http://reports.yourcompany.com/Reports/Pages/Report.aspx?ItemPath='</span>
  <span style="color: #66cc66;">,</span>@AdminEmail <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Business Intelligence &lt;BusinessIntelligence@yourcompany.com&gt;'</span>
  <span style="color: #66cc66;">,</span>@FromAddress <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Business Intelligence &lt;BusinessIntelligence@yourcompany.com&gt;'</span>
  <span style="color: #66cc66;">,</span>@MailDomain <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'yourcompany.com'</span>
  <span style="color: #66cc66;">,</span>@NTDomain <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'AWESOMECO'</span></pre></div></div>

<p><em>Set paramaters as follows:</em></p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">@ReportServerBaseURL VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1024</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #808080; font-style: italic;">-- The url string needed view a report (including the ItemPath querystring variable</span>
<span style="color: #808080; font-style: italic;">-- An example is 'http://reports.yourcompany.com/Reports/Pages/Report.aspx?ItemPath='</span>
<span style="color: #808080; font-style: italic;">-- You can obtain this by simply viewing a report and looking at the address bar	</span>
&nbsp;
@AdminEmail VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #808080; font-style: italic;">-- Email that will receive digest emails</span>
&nbsp;
@FromAddress VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #808080; font-style: italic;">-- From email, they should be able to reply to this with questions</span>
&nbsp;
@MailDomain VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #808080; font-style: italic;">-- Domain that you can send email to by appending their user name to</span>
<span style="color: #808080; font-style: italic;">-- So if you set this to 'example.com' and your username is EXAMPLE\tlaqua</span>
<span style="color: #808080; font-style: italic;">-- it would attempt to send an email to tlaqua@example.com</span>
&nbsp;
@NTDomain VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #808080; font-style: italic;">-- NTDomain for usernames.  If your username is EXAMPLE\tlaqua, 'EXAMPLE'</span>
<span style="color: #808080; font-style: italic;">-- is the @NTDomain</span>
&nbsp;
@ReportServerDatabase VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'ReportServer'</span>
<span style="color: #808080; font-style: italic;">-- Name of ReportServer database - MUST be on the server procedure runs on </span>
&nbsp;
@ReportServerSchema VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'dbo'</span>
<span style="color: #808080; font-style: italic;">-- Schema for ReportServer tables</span>
&nbsp;
@HoursToCheck INT <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span>
<span style="color: #808080; font-style: italic;">-- This should conicide with how often you run the procedure</span>
<span style="color: #808080; font-style: italic;">-- If you run the procedure hourly, set this to 1 so it checks 1 hour back</span>
<span style="color: #808080; font-style: italic;">-- If you run the procedure daily, set it to 24</span>
&nbsp;
@HourSchedule INT <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">16777215</span>
<span style="color: #808080; font-style: italic;">-- Bitmask for hours of the day to run.  If you want it to only run if</span>
<span style="color: #808080; font-style: italic;">-- it is 9AM, 6PM, and 11PM, set this value to 8651264:</span>
<span style="color: #808080; font-style: italic;">-- POWER(2, 9) + POWER(2, 18) + POWER(2, 23) = 8651264</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://timlaqua.com/2011/04/monitoring-failed-report-server-subscriptions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

