<?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; t-sql</title>
	<atom:link href="http://timlaqua.com/tag/t-sql/feed/" rel="self" type="application/rss+xml" />
	<link>http://timlaqua.com</link>
	<description>Thoughts and Code from Tim Laqua</description>
	<lastBuildDate>Sun, 09 May 2010 15:25:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Clone Analysis Services Partitions with PowerShell</title>
		<link>http://timlaqua.com/2010/01/clone-analysis-services-partitions-with-powershell/</link>
		<comments>http://timlaqua.com/2010/01/clone-analysis-services-partitions-with-powershell/#comments</comments>
		<pubDate>Fri, 15 Jan 2010 20:45:20 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Scripts & Code]]></category>
		<category><![CDATA[amo]]></category>
		<category><![CDATA[analysis services]]></category>
		<category><![CDATA[bi]]></category>
		<category><![CDATA[business intelligence]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[t-sql]]></category>

		<guid isPermaLink="false">http://timlaqua.com/?p=322</guid>
		<description><![CDATA[Most of us with large Analysis Services cubes partition our cubes by month or year or some other time-based slice and we have all, at one point or another, developed some way to create partitions for new months on-demand. Often, the solution to this seems to be a C# console application or SSIS package using [...]]]></description>
			<content:encoded><![CDATA[<p>Most of us with large Analysis Services cubes partition our cubes by month or year or some other time-based slice and we have all, at one point or another, developed some way to create partitions for new months on-demand.  Often, the solution to this seems to be a C# console application or SSIS package using AMO to create a new partition based off an existing partition.  The problem I see with this is that maintaining it requires opening up the project or package, making changes, re-compiling, deploying, testing, deploying to production, verifying, etc.  It also requires that whoever is going to maintain it is comfortable with C#.</p>
<p>To simplify the maintenance and get rid of the "black box" factor that utility apps like this tend to have, I put together a PowerShell script to do the same thing and a stored procedure to call the script.  Really, it doesn't matter what you use as you're most likely using an almost identical chunk of code to get your new partition created - my argument is that using PowerShell instead of C# or SSIS reduces the cost of maintenance, improves readability, and facilitates better understanding throughout your team.<br />
<span id="more-322"></span><br />
<em>The PowerShell Script: cloneSSASPartition.ps1</em></p>

<div class="wp_syntax"><div class="code"><pre class="powershell" style="font-family:monospace;"><span style="color: #0000FF;">param</span><span style="color: #000000;">&#40;</span>
   <span style="color: #000000;">&#91;</span><span style="color: #008080;">string</span><span style="color: #000000;">&#93;</span> <span style="color: #800080;">$ServerName</span><span style="color: pink;">,</span> 		<span style="color: pink;">&lt;</span><span style="color: #008000;"># The name of the Analysis Services Instance #&gt;</span>
   <span style="color: #000000;">&#91;</span><span style="color: #008080;">string</span><span style="color: #000000;">&#93;</span> <span style="color: #800080;">$DatabaseName</span><span style="color: pink;">,</span> 		<span style="color: pink;">&lt;</span><span style="color: #008000;"># The name of the Database our Cube is in #&gt;</span>
   <span style="color: #000000;">&#91;</span><span style="color: #008080;">string</span><span style="color: #000000;">&#93;</span> <span style="color: #800080;">$CubeName</span><span style="color: pink;">,</span>     		<span style="color: pink;">&lt;</span><span style="color: #008000;"># The name of the Cube that our Measure Group is in #&gt;</span>
   <span style="color: #000000;">&#91;</span><span style="color: #008080;">string</span><span style="color: #000000;">&#93;</span> <span style="color: #800080;">$MeasureGroupName</span><span style="color: pink;">,</span> 	<span style="color: pink;">&lt;</span><span style="color: #008000;"># The name of the Measure Group that our Partition is in #&gt;</span>
   <span style="color: #000000;">&#91;</span><span style="color: #008080;">string</span><span style="color: #000000;">&#93;</span> <span style="color: #800080;">$SourcePartitionName</span><span style="color: pink;">,</span> 	<span style="color: pink;">&lt;</span><span style="color: #008000;"># The name of the Partition we want to merge in to another partition #&gt;</span>
   <span style="color: #000000;">&#91;</span><span style="color: #008080;">string</span><span style="color: #000000;">&#93;</span> <span style="color: #800080;">$NewPartitionName</span><span style="color: pink;">,</span> 	<span style="color: pink;">&lt;</span><span style="color: #008000;"># The desired name of the new partition #&gt;</span>
   <span style="color: #000000;">&#91;</span><span style="color: #008080;">string</span><span style="color: #000000;">&#93;</span> <span style="color: #800080;">$NewPartitionQuery</span> 	<span style="color: pink;">&lt;</span><span style="color: #008000;"># The Query source for the new partition (will use the same datasource as the SourcePartition #&gt;</span>
<span style="color: #000000;">&#41;</span>
&nbsp;
<span style="color: #000000;">&#91;</span><span style="color: #008080;">System.Reflection.Assembly</span><span style="color: #000000;">&#93;</span>::<span style="color: #800000;">LoadWithPartialName</span><span style="color: #000000;">&#40;</span><span style="color: #800000;">&quot;Microsoft.AnalysisServices&quot;</span><span style="color: #000000;">&#41;</span> <span style="color: pink;">&gt;</span><span style="color: #800080;">$NULL</span>
&nbsp;
<span style="color: #800080;">$server</span> <span style="color: pink;">=</span> <span style="color: #008080; font-weight: bold;">New-Object</span> Microsoft.AnalysisServices.Server
<span style="color: #800080;">$server</span>.Connect<span style="color: #000000;">&#40;</span><span style="color: #800080;">$ServerName</span><span style="color: #000000;">&#41;</span>
&nbsp;
<span style="color: #800080;">$database</span> <span style="color: pink;">=</span> <span style="color: #800080;">$server</span>.Databases.GetByName<span style="color: #000000;">&#40;</span><span style="color: #800080;">$DatabaseName</span><span style="color: #000000;">&#41;</span>
<span style="color: #800080;">$cube</span> <span style="color: pink;">=</span> <span style="color: #800080;">$database</span>.Cubes.GetByName<span style="color: #000000;">&#40;</span><span style="color: #800080;">$CubeName</span><span style="color: #000000;">&#41;</span>
<span style="color: #800080;">$measureGroup</span> <span style="color: pink;">=</span> <span style="color: #800080;">$cube</span>.MeasureGroups.FindByName<span style="color: #000000;">&#40;</span><span style="color: #800080;">$MeasureGroupName</span><span style="color: #000000;">&#41;</span>
<span style="color: #800080;">$sourcePartition</span> <span style="color: pink;">=</span> <span style="color: #800080;">$measureGroup</span>.Partitions.GetByName<span style="color: #000000;">&#40;</span><span style="color: #800080;">$SourcePartitionName</span><span style="color: #000000;">&#41;</span>
<span style="color: #800080;">$sourceQueryBinding</span> <span style="color: pink;">=</span> <span style="color: #800080;">$sourcePartition</span>.Source
&nbsp;
<span style="color: #800080;">$newPartition</span> <span style="color: pink;">=</span> <span style="color: #800080;">$sourcePartition</span>.Clone<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
<span style="color: #800080;">$newPartition</span>.ID <span style="color: pink;">=</span> <span style="color: #800080;">$NewPartitionName</span>
<span style="color: #800080;">$newPartition</span>.Name <span style="color: pink;">=</span> <span style="color: #800080;">$NewPartitionName</span>
<span style="color: #800080;">$measureGroup</span>.Partitions.Add<span style="color: #000000;">&#40;</span><span style="color: #800080;">$newPartition</span><span style="color: #000000;">&#41;</span> <span style="color: pink;">&gt;</span> <span style="color: #800080;">$NULL</span>
<span style="color: #800080;">$newPartition</span>.Source <span style="color: pink;">=</span> <span style="color: #008080; font-weight: bold;">New-Object</span> Microsoft.AnalysisServices.QueryBinding<span style="color: #000000;">&#40;</span><span style="color: #800080;">$sourceQueryBinding</span>.DataSourceID<span style="color: pink;">,</span> <span style="color: #800080;">$NewPartitionQuery</span><span style="color: #000000;">&#41;</span>
<span style="color: #800080;">$newPartition</span>.Update<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
&nbsp;
<span style="color: #800080;">$server</span>.Disconnect<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span></pre></div></div>

<p><em>The stored procedure to call the script: [Utility_CloneSSASPartition_S01] - assumes you placed cloneSSASPartition.ps1 at the root of the C: drive.  If you put it elsewhere, update the proc to reflect the actual location.</em></p>

<div class="wp_syntax"><div class="code"><pre class="tsql" style="font-family:monospace;"><span style="color: #0000FF;">SET</span> ANSI_<span style="color: #808080;">NULL</span>S <span style="color: #0000FF;">ON</span>
GO
&nbsp;
<span style="color: #0000FF;">SET</span> QUOTED_IDENTIFIER <span style="color: #0000FF;">ON</span>
GO
&nbsp;
<span style="color: #008080;">/*************************************************************************************
***
*** Procedure:  		[Utility_CloneSSASPartition]
*** Purpose:		Executes PowerShell script to clone a SSAS partition
***			
***			
*** Author:		tl
*** Date Created:		2010-01-15
*** 
*** Revision History
*** Date		Author			Description
*** 2010-01-15	tl			Created
*************************************************************************************/</span>
&nbsp;
<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>Utility_CloneSSASPartition_S01<span style="color: #808080;">&#93;</span>
<span style="color: #808080;">&#40;</span>
	@ServerName <span style="color: #0000FF;">AS</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>,
	@DatabaseName <span style="color: #0000FF;">AS</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>,
	@CubeName <span style="color: #0000FF;">AS</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>,
	@MeasureGroupName <span style="color: #0000FF;">AS</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>,
	@SourcePartitionName <span style="color: #0000FF;">AS</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>,
	@NewPartitionName <span style="color: #0000FF;">AS</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>,
	@NewPartitionQuery <span style="color: #0000FF;">AS</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>
<span style="color: #0000FF;">AS</span> 
&nbsp;
<span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">NOCOUNT</span> <span style="color: #0000FF;">ON</span>
<span style="color: #0000FF;">DECLARE</span> @cmd <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">8000</span><span style="color: #808080;">&#41;</span>
<span style="color: #0000FF;">SET</span> @cmd <span style="color: #808080;">=</span> 
	<span style="color: #FF0000;">'powershell.exe -Command &quot;&amp; {'</span>
	<span style="color: #808080;">+</span> <span style="color: #FF0000;">' C:<span style="color: #000099; font-weight: bold;">\c</span>loneSSASPartition.ps1'</span>
	<span style="color: #808080;">+</span> <span style="color: #FF0000;">' -ServerName:<span style="color: #000099; font-weight: bold;">\&quot;</span>'</span> <span style="color: #808080;">+</span> @ServerName <span style="color: #808080;">+</span> <span style="color: #FF0000;">'<span style="color: #000099; font-weight: bold;">\&quot;</span>'</span>
	<span style="color: #808080;">+</span> <span style="color: #FF0000;">' -DatabaseName:<span style="color: #000099; font-weight: bold;">\&quot;</span>'</span> <span style="color: #808080;">+</span> @DatabaseName <span style="color: #808080;">+</span> <span style="color: #FF0000;">'<span style="color: #000099; font-weight: bold;">\&quot;</span>'</span>
	<span style="color: #808080;">+</span> <span style="color: #FF0000;">' -CubeName:<span style="color: #000099; font-weight: bold;">\&quot;</span>'</span> <span style="color: #808080;">+</span> @CubeName <span style="color: #808080;">+</span> <span style="color: #FF0000;">'<span style="color: #000099; font-weight: bold;">\&quot;</span>'</span>
	<span style="color: #808080;">+</span> <span style="color: #FF0000;">' -MeasureGroupName:<span style="color: #000099; font-weight: bold;">\&quot;</span>'</span> <span style="color: #808080;">+</span> @MeasureGroupName <span style="color: #808080;">+</span> <span style="color: #FF0000;">'<span style="color: #000099; font-weight: bold;">\&quot;</span>'</span>
	<span style="color: #808080;">+</span> <span style="color: #FF0000;">' -SourcePartitionName:<span style="color: #000099; font-weight: bold;">\&quot;</span>'</span> <span style="color: #808080;">+</span> @SourcePartitionName <span style="color: #808080;">+</span> <span style="color: #FF0000;">'<span style="color: #000099; font-weight: bold;">\&quot;</span>'</span>
	<span style="color: #808080;">+</span> <span style="color: #FF0000;">' -NewPartitionName:<span style="color: #000099; font-weight: bold;">\&quot;</span>'</span> <span style="color: #808080;">+</span> @NewPartitionName <span style="color: #808080;">+</span> <span style="color: #FF0000;">'<span style="color: #000099; font-weight: bold;">\&quot;</span>'</span>
	<span style="color: #808080;">+</span> <span style="color: #FF0000;">' -NewPartitionQuery:<span style="color: #000099; font-weight: bold;">\&quot;</span>'</span> <span style="color: #808080;">+</span> @NewPartitionQuery <span style="color: #808080;">+</span> <span style="color: #FF0000;">'<span style="color: #000099; font-weight: bold;">\&quot;</span>}&quot;'</span>
&nbsp;
<span style="color: #0000FF;">PRINT</span> @cmd
<span style="color: #0000FF;">EXEC</span> xp_cmdshell @cmd</pre></div></div>

<p>And, finally, we execute it</p>

<div class="wp_syntax"><div class="code"><pre class="tsql" style="font-family:monospace;"><span style="color: #0000FF;">EXEC</span> <span style="color: #808080;">&#91;</span>dbo<span style="color: #808080;">&#93;</span>.<span style="color: #808080;">&#91;</span>Utility_CloneSSASPartition_S01<span style="color: #808080;">&#93;</span>
	 @ServerName <span style="color: #808080;">=</span> <span style="color: #FF0000;">'TESTSERVER'</span>
	,@DatabaseName <span style="color: #808080;">=</span> <span style="color: #FF0000;">'TestDatabase'</span>
	,@CubeName <span style="color: #808080;">=</span> <span style="color: #FF0000;">'TestCube'</span>
	,@MeasureGroupName <span style="color: #808080;">=</span> <span style="color: #FF0000;">'Test Measure Group'</span>
	,@SourcePartitionName <span style="color: #808080;">=</span> <span style="color: #FF0000;">'Test Partition - 200912'</span>
	,@NewPartitionName <span style="color: #808080;">=</span> <span style="color: #FF0000;">'Test Partition - 201001'</span>
	,@NewPartitionQuery <span style="color: #808080;">=</span> <span style="color: #FF0000;">'SELECT * FROM dbo.FactTableMonth('</span><span style="color: #FF0000;">'1/1/2010'</span><span style="color: #FF0000;">', '</span><span style="color: #FF0000;">'2/1/2010'</span><span style="color: #FF0000;">')'</span></pre></div></div>

<p>Again, I'm not saying there's anything "wrong" with using C# or SSIS Packages to do this sort of thing, I'm just pointing out that C# isn't always the answer - especially when someone other than you needs to maintain this thing in the future.  Keep it simple.</p>
]]></content:encoded>
			<wfw:commentRss>http://timlaqua.com/2010/01/clone-analysis-services-partitions-with-powershell/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Maintaining a Type 1 Slowly Changing Dimension (SCD) using T-SQL</title>
		<link>http://timlaqua.com/2009/05/maintaining-a-type-1-slowly-changing-dimension-scd-using-t-sql/</link>
		<comments>http://timlaqua.com/2009/05/maintaining-a-type-1-slowly-changing-dimension-scd-using-t-sql/#comments</comments>
		<pubDate>Sat, 23 May 2009 16:37:35 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Scripts & Code]]></category>
		<category><![CDATA[bi]]></category>
		<category><![CDATA[business intelligence]]></category>
		<category><![CDATA[data warehouse]]></category>
		<category><![CDATA[scd]]></category>
		<category><![CDATA[slowly changing dimension]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[ssis]]></category>
		<category><![CDATA[t-sql]]></category>

		<guid isPermaLink="false">http://timlaqua.com/?p=224</guid>
		<description><![CDATA[A few days ago, one of our SSIS packages that maintained a Type 1 Slowly Changing Dimension (SCD) of about 1 million rows crept up to 15 minutes of runtime. Now this doesn't sound too bad, but this is part of our hourly batches, so 15 minutes is 25% of our entire processing window. The [...]]]></description>
			<content:encoded><![CDATA[<p>A few days ago, one of our SSIS packages that maintained a Type 1 Slowly Changing Dimension (SCD) of about 1 million rows crept up to 15 minutes of runtime.  Now this doesn't sound too bad, but this is part of our hourly batches, so 15 minutes is 25% of our entire processing window.  The package was using the Slowly Changing Dimension Wizard transformation - we were doing the standard OLEDB Source (which basically represented how the SCD "should" look) and then sending it to the SCD transform and letting it figure out what needed to be inserted and updated.  One option was to switch to lookups instead of the SCD wizard to speed things up, maybe even some fancy checksum voodoo for the updates (see <a href="http://blog.stevienova.com/2008/11/22/ssis-slowly-changing-dimensions-with-checksum/">http://blog.stevienova.com/2008/11/22/ssis-slowly-changing-dimensions-with-checksum/</a> for an example).  Then after thinking about it a little more - why are we sending a million rows down the pipeline every hour?  We know only a small percentage of these are new - and another small percentage needs to be updated.  Well, we can just write a quick SQL query to get us just those sets and the package would be much more efficient!  </p>
<p>Wait a tick - why would we give the rows to SSIS if all it is going to do insert one set and update the other?  Let's just do it all in T-SQL:<span id="more-224"></span></p>
<p><em>The following tables and dim are fictional - I just need to make up a star schema DIM to illustrate the approach</em></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> #Temp_SCDInserts <span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>PartId<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">INT</span><span style="color: #808080;">&#41;</span>
&nbsp;
<span style="color: #008080;">-- INSERTS for new Parts</span>
<span style="color: #0000FF;">INSERT</span> <span style="color: #0000FF;">INTO</span> #Temp_SCDInserts
<span style="color: #0000FF;">SELECT</span>   
	<span style="color: #808080;">&#91;</span>PartId<span style="color: #808080;">&#93;</span>
<span style="color: #0000FF;">FROM</span> 
	Part a <span style="color: #0000FF;">WITH</span><span style="color: #808080;">&#40;</span>NOLOCK<span style="color: #808080;">&#41;</span>
	<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span> PartType b <span style="color: #0000FF;">WITH</span><span style="color: #808080;">&#40;</span>NOLOCK<span style="color: #808080;">&#41;</span> 
		<span style="color: #0000FF;">ON</span> a.<span style="color: #202020;">PartTypeId</span> <span style="color: #808080;">=</span> b.<span style="color: #202020;">PartTypeId</span>
	<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span> PartSupplier c <span style="color: #0000FF;">WITH</span><span style="color: #808080;">&#40;</span>NOLOCK<span style="color: #808080;">&#41;</span> 
		<span style="color: #0000FF;">ON</span> a.<span style="color: #202020;">PartSupplierId</span> <span style="color: #808080;">=</span> c.<span style="color: #202020;">PartSupplierId</span>
	<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span> PartSupplierCategory d <span style="color: #0000FF;">WITH</span><span style="color: #808080;">&#40;</span>NOLOCK<span style="color: #808080;">&#41;</span> 
		<span style="color: #0000FF;">ON</span> c.<span style="color: #202020;">PartSupplierCategoryId</span> <span style="color: #808080;">=</span> d.<span style="color: #202020;">PartSupplierCategoryId</span>
<span style="color: #0000FF;">EXCEPT</span>
<span style="color: #0000FF;">SELECT</span>
	<span style="color: #808080;">&#91;</span>PartId<span style="color: #808080;">&#93;</span>	
<span style="color: #0000FF;">FROM</span>
	DW.<span style="color: #202020;">dbo</span>.<span style="color: #202020;">Dim_Part</span> <span style="color: #0000FF;">WITH</span><span style="color: #808080;">&#40;</span>NOLOCK<span style="color: #808080;">&#41;</span>
&nbsp;
<span style="color: #008080;">-- UPDATES</span>
<span style="color: #0000FF;">SELECT</span> 
	 dim.<span style="color: #808080;">&#91;</span>PartKeyId<span style="color: #808080;">&#93;</span>
	,a.<span style="color: #808080;">&#91;</span>PartName<span style="color: #808080;">&#93;</span>
	,b.<span style="color: #808080;">&#91;</span>PartTypeId<span style="color: #808080;">&#93;</span>
	,b.<span style="color: #808080;">&#91;</span>PartTypeName<span style="color: #808080;">&#93;</span>
	,c.<span style="color: #808080;">&#91;</span>PartSupplierId<span style="color: #808080;">&#93;</span>
	,c.<span style="color: #808080;">&#91;</span>PartSupplierName<span style="color: #808080;">&#93;</span>
	,d.<span style="color: #808080;">&#91;</span>PartSupplierCategoryId<span style="color: #808080;">&#93;</span>
	,d.<span style="color: #808080;">&#91;</span>PartSupplierCategoryName<span style="color: #808080;">&#93;</span>
<span style="color: #0000FF;">INTO</span> #Temp_SCDUpdates
<span style="color: #0000FF;">FROM</span> DW.<span style="color: #202020;">dbo</span>.<span style="color: #202020;">Dim_Part</span> dim <span style="color: #0000FF;">WITH</span><span style="color: #808080;">&#40;</span>NOLOCK<span style="color: #808080;">&#41;</span>
	<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span> Part a <span style="color: #0000FF;">WITH</span><span style="color: #808080;">&#40;</span>NOLOCK<span style="color: #808080;">&#41;</span>
		<span style="color: #0000FF;">ON</span> dim.<span style="color: #202020;">PartId</span> <span style="color: #808080;">=</span> a.<span style="color: #202020;">PartId</span> <span style="color: #008080;">-- Business Key</span>
	<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span> PartType b <span style="color: #0000FF;">WITH</span><span style="color: #808080;">&#40;</span>NOLOCK<span style="color: #808080;">&#41;</span> 
		<span style="color: #0000FF;">ON</span> a.<span style="color: #202020;">PartTypeId</span> <span style="color: #808080;">=</span> b.<span style="color: #202020;">PartTypeId</span>
	<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span> PartSupplier c <span style="color: #0000FF;">WITH</span><span style="color: #808080;">&#40;</span>NOLOCK<span style="color: #808080;">&#41;</span> 
		<span style="color: #0000FF;">ON</span> a.<span style="color: #202020;">PartSupplierId</span> <span style="color: #808080;">=</span> c.<span style="color: #202020;">PartSupplierId</span>
	<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span> PartSupplierCategory d <span style="color: #0000FF;">WITH</span><span style="color: #808080;">&#40;</span>NOLOCK<span style="color: #808080;">&#41;</span> 
		<span style="color: #0000FF;">ON</span> c.<span style="color: #202020;">PartSupplierCategoryId</span> <span style="color: #808080;">=</span> d.<span style="color: #202020;">PartSupplierCategoryId</span>
<span style="color: #0000FF;">WHERE</span>
	dim.<span style="color: #202020;">PartName</span> <span style="color: #808080;">&lt;&gt;</span> a.<span style="color: #202020;">PartName</span>
	<span style="color: #808080;">OR</span> dim.<span style="color: #202020;">PartTypeId</span> <span style="color: #808080;">&lt;&gt;</span> b.<span style="color: #202020;">PartTypeId</span>
	<span style="color: #808080;">OR</span> dim.<span style="color: #202020;">PartTypeName</span> <span style="color: #808080;">&lt;&gt;</span> b.<span style="color: #202020;">PartTypeName</span>
	<span style="color: #808080;">OR</span> dim.<span style="color: #202020;">PartSupplierId</span> <span style="color: #808080;">&lt;&gt;</span> c.<span style="color: #202020;">PartSupplierId</span>
	<span style="color: #808080;">OR</span> dim.<span style="color: #202020;">PartSupplierName</span> <span style="color: #808080;">&lt;&gt;</span> c.<span style="color: #202020;">PartSupplierName</span>
	<span style="color: #808080;">OR</span> dim.<span style="color: #202020;">PartSupplierCategoryId</span> <span style="color: #808080;">&lt;&gt;</span> d.<span style="color: #202020;">PartSupplierCategoryId</span>
	<span style="color: #808080;">OR</span> dim.<span style="color: #202020;">PartSupplierCategoryName</span>	<span style="color: #808080;">&lt;&gt;</span> d.<span style="color: #202020;">PartSupplierCategoryName</span>
&nbsp;
<span style="color: #008080;">-- INSERT new records</span>
<span style="color: #0000FF;">INSERT</span> <span style="color: #0000FF;">INTO</span> <span style="color: #808080;">&#91;</span>DW<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>Dim_Part<span style="color: #808080;">&#93;</span>
	<span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>PartId<span style="color: #808080;">&#93;</span>
	,<span style="color: #808080;">&#91;</span>PartName<span style="color: #808080;">&#93;</span>
	,<span style="color: #808080;">&#91;</span>PartTypeId<span style="color: #808080;">&#93;</span>
	,<span style="color: #808080;">&#91;</span>PartTypeName<span style="color: #808080;">&#93;</span>
	,<span style="color: #808080;">&#91;</span>PartSupplierId<span style="color: #808080;">&#93;</span>
	,<span style="color: #808080;">&#91;</span>PartSupplierName<span style="color: #808080;">&#93;</span>
	,<span style="color: #808080;">&#91;</span>PartSupplierCategoryId<span style="color: #808080;">&#93;</span>
	,<span style="color: #808080;">&#91;</span>PartSupplierCategoryName<span style="color: #808080;">&#93;</span><span style="color: #808080;">&#41;</span>
<span style="color: #0000FF;">SELECT</span> 
	 a.<span style="color: #808080;">&#91;</span>PartId<span style="color: #808080;">&#93;</span>
	,a.<span style="color: #808080;">&#91;</span>PartName<span style="color: #808080;">&#93;</span>
	,b.<span style="color: #808080;">&#91;</span>PartTypeId<span style="color: #808080;">&#93;</span>
	,b.<span style="color: #808080;">&#91;</span>PartTypeName<span style="color: #808080;">&#93;</span>
	,c.<span style="color: #808080;">&#91;</span>PartSupplierId<span style="color: #808080;">&#93;</span>
	,c.<span style="color: #808080;">&#91;</span>PartSupplierName<span style="color: #808080;">&#93;</span>
	,d.<span style="color: #808080;">&#91;</span>PartSupplierCategoryId<span style="color: #808080;">&#93;</span>
	,d.<span style="color: #808080;">&#91;</span>PartSupplierCategoryName<span style="color: #808080;">&#93;</span>
<span style="color: #0000FF;">FROM</span> #Temp_SCDInserts i
	<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span> Part a <span style="color: #0000FF;">WITH</span><span style="color: #808080;">&#40;</span>NOLOCK<span style="color: #808080;">&#41;</span>
		<span style="color: #0000FF;">ON</span> i.<span style="color: #202020;">PartId</span> <span style="color: #808080;">=</span> a.<span style="color: #202020;">PartId</span> <span style="color: #008080;">-- Business Key</span>
	<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span> PartType b <span style="color: #0000FF;">WITH</span><span style="color: #808080;">&#40;</span>NOLOCK<span style="color: #808080;">&#41;</span> 
		<span style="color: #0000FF;">ON</span> a.<span style="color: #202020;">PartTypeId</span> <span style="color: #808080;">=</span> b.<span style="color: #202020;">PartTypeId</span>
	<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span> PartSupplier c <span style="color: #0000FF;">WITH</span><span style="color: #808080;">&#40;</span>NOLOCK<span style="color: #808080;">&#41;</span> 
		<span style="color: #0000FF;">ON</span> a.<span style="color: #202020;">PartSupplierId</span> <span style="color: #808080;">=</span> c.<span style="color: #202020;">PartSupplierId</span>
	<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span> PartSupplierCategory d <span style="color: #0000FF;">WITH</span><span style="color: #808080;">&#40;</span>NOLOCK<span style="color: #808080;">&#41;</span> 
		<span style="color: #0000FF;">ON</span> c.<span style="color: #202020;">PartSupplierCategoryId</span> <span style="color: #808080;">=</span> d.<span style="color: #202020;">PartSupplierCategoryId</span>
&nbsp;
<span style="color: #008080;">-- UPDATE existing records</span>
<span style="color: #0000FF;">UPDATE</span> <span style="color: #808080;">&#91;</span>DW<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>Dim_Part<span style="color: #808080;">&#93;</span>
<span style="color: #0000FF;">SET</span>
	 <span style="color: #808080;">&#91;</span>PartName<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>PartName<span style="color: #808080;">&#93;</span>
	,<span style="color: #808080;">&#91;</span>PartTypeId<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>PartTypeId<span style="color: #808080;">&#93;</span>
	,<span style="color: #808080;">&#91;</span>PartTypeName<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>PartTypeName<span style="color: #808080;">&#93;</span>
	,<span style="color: #808080;">&#91;</span>PartSupplierId<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>PartSupplierId<span style="color: #808080;">&#93;</span>
	,<span style="color: #808080;">&#91;</span>PartSupplierName<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>PartSupplierName<span style="color: #808080;">&#93;</span>
	,<span style="color: #808080;">&#91;</span>PartSupplierCategoryId<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>PartSupplierCategoryId<span style="color: #808080;">&#93;</span>
	,<span style="color: #808080;">&#91;</span>PartSupplierCategoryName<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> b.<span style="color: #808080;">&#91;</span>PartSupplierCategoryName<span style="color: #808080;">&#93;</span>
<span style="color: #0000FF;">FROM</span> 
	<span style="color: #808080;">&#91;</span>DW<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>Dim_Part<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> a
	<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span> #Temp_SCDUpdates <span style="color: #0000FF;">AS</span> b 
		<span style="color: #0000FF;">ON</span> a.<span style="color: #202020;">PartKeyId</span> <span style="color: #808080;">=</span> b.<span style="color: #202020;">PartKeyId</span>  <span style="color: #008080;">-- Join on Business Keys or Surrogate Key</span>
&nbsp;
&nbsp;
<span style="color: #0000FF;">DROP</span> <span style="color: #0000FF;">TABLE</span> #Temp_SCDInserts
<span style="color: #0000FF;">DROP</span> <span style="color: #0000FF;">TABLE</span> #Temp_SCDUpdates</pre></div></div>

<p>The results?  Our 15 minute SSIS package has been replaced with a few lines of T-SQL and it now runs in less than 90 seconds.  Nice.</p>
]]></content:encoded>
			<wfw:commentRss>http://timlaqua.com/2009/05/maintaining-a-type-1-slowly-changing-dimension-scd-using-t-sql/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Parsing QueryString (GET) Variables From a URL using T-SQL</title>
		<link>http://timlaqua.com/2009/05/parsing-querystring-get-variables-from-a-url-using-t-sql/</link>
		<comments>http://timlaqua.com/2009/05/parsing-querystring-get-variables-from-a-url-using-t-sql/#comments</comments>
		<pubDate>Sat, 23 May 2009 14:59:33 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Scripts & Code]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[string parsing]]></category>
		<category><![CDATA[t-sql]]></category>
		<category><![CDATA[table valued function]]></category>

		<guid isPermaLink="false">http://timlaqua.com/?p=216</guid>
		<description><![CDATA[First of all - I know, don't do this. The application that put the URL in the column in the first place is MUCH better at handling URLs and ideally, you would just add columns for the GET variables you're after and have the application put those in. Parsing them out after the fact from [...]]]></description>
			<content:encoded><![CDATA[<p>First of all - I know, don't do this.  The application that put the URL in the column in the first place is MUCH better at handling URLs and ideally, you would just add columns for the GET variables you're after and have the application put those in.  Parsing them out after the fact from a VARCHAR field is insane.</p>
<p>So now we're here and we need to do that thing that we said we shouldn't do.  My approach is to use a Table Valued Function that only returns one column - the value of the variable or NULL if it can't find the variable in the querystring.<span id="more-216"></span></p>
<p><em>Example</em></p>

<div class="wp_syntax"><div class="code"><pre class="tsql" style="font-family:monospace;"><span style="color: #0000FF;">SELECT</span>
	a.<span style="color: #808080;">&#91;</span>Id<span style="color: #808080;">&#93;</span>,
	b.<span style="color: #808080;">&#91;</span>GetVariableValue<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #808080;">&#91;</span>Foo<span style="color: #808080;">&#93;</span>,
	c.<span style="color: #808080;">&#91;</span>GetVariableValue<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</span> <span style="color: #808080;">&#91;</span>Bar<span style="color: #808080;">&#93;</span>
<span style="color: #0000FF;">FROM</span>
	<span style="color: #808080;">&#91;</span>dbo<span style="color: #808080;">&#93;</span>.<span style="color: #808080;">&#91;</span>SourceTable<span style="color: #808080;">&#93;</span> a
	<span style="color: #808080;">CROSS</span> APPLY <span style="color: #808080;">&#91;</span>dbo<span style="color: #808080;">&#93;</span>.<span style="color: #808080;">&#91;</span>Utility_UrlParseGetVariable_F01<span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>URL<span style="color: #808080;">&#93;</span>, <span style="color: #FF0000;">'foo'</span>, <span style="color: #000;">0</span><span style="color: #808080;">&#41;</span> b
	<span style="color: #808080;">CROSS</span> APPLY <span style="color: #808080;">&#91;</span>dbo<span style="color: #808080;">&#93;</span>.<span style="color: #808080;">&#91;</span>Utility_UrlParseGetVariable_F01<span style="color: #808080;">&#93;</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>URL<span style="color: #808080;">&#93;</span>, <span style="color: #FF0000;">'bar'</span>, <span style="color: #000;">0</span><span style="color: #808080;">&#41;</span> c</pre></div></div>

<p><em>Table Valued Function</em></p>

<div class="wp_syntax"><div class="code"><pre class="tsql" style="font-family:monospace;"><span style="color: #008080;">/*************************************************************************************
***
*** Procedure:  		[Utility_UrlParseGetVariable_F01]
*** Purpose:		    Attempts to parse a given GET variable out of a URL string
***				
***			
*** Author:		      tl
*** Date Created:	  2009-05-22
*** 
*** Revision History
*** Date		Author			Description
*** 2009-05-22	tl				Created
*************************************************************************************/</span>
<span style="color: #0000FF;">ALTER</span> <span style="color: #0000FF;">FUNCTION</span> <span style="color: #808080;">&#91;</span>dbo<span style="color: #808080;">&#93;</span>.<span style="color: #808080;">&#91;</span>Utility_UrlParseGetVariable_F01<span style="color: #808080;">&#93;</span> 
<span style="color: #808080;">&#40;</span>
	@Url <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">2048</span><span style="color: #808080;">&#41;</span>,
	@VariableName <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>
<span style="color: #0000FF;">RETURNS</span> @GetVariable <span style="color: #0000FF;">TABLE</span> <span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>GetVariableValue<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>
<span style="color: #0000FF;">AS</span>
<span style="color: #0000FF;">BEGIN</span>
&nbsp;
	<span style="color: #0000FF;">DECLARE</span> @<span style="color: #FF00FF;">SUBSTRING</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: #0000FF;">DECLARE</span> @variableValue <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;">SET</span> @VariableName <span style="color: #808080;">=</span> @VariableName <span style="color: #808080;">+</span> <span style="color: #FF0000;">'='</span>
&nbsp;
	<span style="color: #008080;">-- Case Insensitive - munge both inputs</span>
	<span style="color: #0000FF;">SET</span> @VariableName <span style="color: #808080;">=</span> <span style="color: #FF00FF;">LOWER</span><span style="color: #808080;">&#40;</span>@VariableName<span style="color: #808080;">&#41;</span>
	<span style="color: #0000FF;">SET</span> @Url <span style="color: #808080;">=</span> <span style="color: #FF00FF;">LOWER</span><span style="color: #808080;">&#40;</span>@Url<span style="color: #808080;">&#41;</span>
&nbsp;
	<span style="color: #0000FF;">IF</span> <span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">CHARINDEX</span><span style="color: #808080;">&#40;</span>@VariableName,@Url<span style="color: #808080;">&#41;</span> <span style="color: #808080;">&gt;</span> <span style="color: #000;">0</span><span style="color: #808080;">&#41;</span>
	<span style="color: #0000FF;">BEGIN</span>
		<span style="color: #0000FF;">SET</span> @<span style="color: #FF00FF;">SUBSTRING</span> <span style="color: #808080;">=</span> <span style="color: #0000FF;">RIGHT</span><span style="color: #808080;">&#40;</span>@Url, <span style="color: #FF00FF;">LEN</span><span style="color: #808080;">&#40;</span>@Url<span style="color: #808080;">&#41;</span> <span style="color: #808080;">-</span> <span style="color: #FF00FF;">CHARINDEX</span><span style="color: #808080;">&#40;</span>@VariableName,@Url<span style="color: #808080;">&#41;</span> <span style="color: #808080;">-</span> <span style="color: #FF00FF;">LEN</span><span style="color: #808080;">&#40;</span>@VariableName<span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span>
		<span style="color: #0000FF;">IF</span> <span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">CHARINDEX</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'&amp;'</span>, @<span style="color: #FF00FF;">SUBSTRING</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">&gt;</span> <span style="color: #000;">0</span><span style="color: #808080;">&#41;</span>
			<span style="color: #0000FF;">SET</span> @variableValue <span style="color: #808080;">=</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">LEFT</span><span style="color: #808080;">&#40;</span>@<span style="color: #FF00FF;">SUBSTRING</span>, <span style="color: #FF00FF;">CHARINDEX</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'&amp;'</span>, @<span style="color: #FF00FF;">SUBSTRING</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">-</span> <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</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>
		<span style="color: #0000FF;">ELSE</span>
			<span style="color: #0000FF;">SET</span> @variableValue <span style="color: #808080;">=</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>@<span style="color: #FF00FF;">SUBSTRING</span> <span style="color: #0000FF;">AS</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;">INSERT</span> <span style="color: #0000FF;">INTO</span> @GetVariable <span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>GetVariableValue<span style="color: #808080;">&#93;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">VALUES</span> <span style="color: #808080;">&#40;</span>@variableValue<span style="color: #808080;">&#41;</span>
	<span style="color: #0000FF;">END</span>
	<span style="color: #0000FF;">ELSE</span>
		<span style="color: #0000FF;">INSERT</span> <span style="color: #0000FF;">INTO</span> @GetVariable <span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>GetVariableValue<span style="color: #808080;">&#93;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">VALUES</span> <span style="color: #808080;">&#40;</span><span style="color: #808080;">NULL</span><span style="color: #808080;">&#41;</span>
&nbsp;
	<span style="color: #0000FF;">RETURN</span>
<span style="color: #0000FF;">END</span></pre></div></div>

<p><em>Issues</em></p>
<ul>
<li>The current TVF munges everything to lower case - the return is lower case as well.  This works fine for me as I was parsing out INT values anyway (so I use ISNULL(...,0) inside a cast) for the actual value.</li>
<li>The way it's written, if you look for the variable 'bar' and the querystring actually has a variable called 'foobar' before it - this function will take the value of 'foobar' and return it (because it's just doing a CHARINDEX for 'bar=' in the querystring</li>
</ul>
<p><em>Why not RegEx via CLR?</em><br />
Because one of the DBAs asked me not to <img src='http://timlaqua.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />   RegEx via CLR is a cleaner and more accurate way to do it.  Better yet, you could use CLR and create a Uri object, then use <code>HttpUtility.ParseQueryString(uri.Query).Name('bar')</code> to get the appropriate value.</p>
]]></content:encoded>
			<wfw:commentRss>http://timlaqua.com/2009/05/parsing-querystring-get-variables-from-a-url-using-t-sql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Cleaner Way to Detect the State of a SQL Server Agent Job In SQL Server 2005</title>
		<link>http://timlaqua.com/2009/05/a-cleaner-way-to-detect-the-state-of-a-sql-server-agent-job-in-sql-server-2005/</link>
		<comments>http://timlaqua.com/2009/05/a-cleaner-way-to-detect-the-state-of-a-sql-server-agent-job-in-sql-server-2005/#comments</comments>
		<pubDate>Sat, 23 May 2009 13:18:38 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Scripts & Code]]></category>
		<category><![CDATA[agent job]]></category>
		<category><![CDATA[sql server 2005]]></category>
		<category><![CDATA[t-sql]]></category>
		<category><![CDATA[table valued function]]></category>

		<guid isPermaLink="false">http://timlaqua.com/?p=212</guid>
		<description><![CDATA[I have always felt that the traditional approach to getting Agent Job status by creating a table and populating it with output from xp_sqlagent_enum_jobs was incredibly crude. So I poked around a bit and came up with a solution using a Table Valued Function that queries sysjobactivity to determine the status of a given job. [...]]]></description>
			<content:encoded><![CDATA[<p>I have always felt that the traditional approach to getting Agent Job status by creating a table and populating it with output from xp_sqlagent_enum_jobs was incredibly crude.  So I poked around a bit and came up with a solution using a Table Valued Function that queries sysjobactivity to determine the status of a given job.  The reason I use a Table Valued Function is because we have a few tables that contain a list of jobs that need to be started at certain points in a given process (and they may or may not already be running) - with the TVF, you can simply CROSS APPLY the function and bob's your uncle.<span id="more-212"></span></p>
<p><em>Example</em><br />
Say you needed to run a chunk of code only if a set of jobs in a given table aren't running:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">	<span style="color: #993333; font-weight: bold;">IF</span>  <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">EXISTS</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #cc66cc;">1</span>
		<span style="color: #993333; font-weight: bold;">FROM</span> AppJobDependency a <span style="color: #993333; font-weight: bold;">WITH</span><span style="color: #66cc66;">&#40;</span>NOLOCK<span style="color: #66cc66;">&#41;</span>
		<span style="color: #993333; font-weight: bold;">CROSS</span> APPLY <span style="color: #66cc66;">&#91;</span>dbo<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">.</span><span style="color: #66cc66;">&#91;</span>Utility_GetAgentJobStatus_F01<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#40;</span>a<span style="color: #66cc66;">.</span><span style="color: #66cc66;">&#91;</span>JobName<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> c
		<span style="color: #993333; font-weight: bold;">WHERE</span> <span style="color: #66cc66;">&#91;</span>JobStatus<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>
	BEGIN
		<span style="color: #808080; font-style: italic;">-- Code goes here</span>
	END</pre></div></div>

<p><em>Table Valued Function</em></p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">/*************************************************************************************
***
*** Procedure:  		[Utility_GetAgentJobStatus_F01]
*** Purpose:		    Get the current status of given agent job
***				
***			
*** Author:		      tl
*** Date Created:	  2009-03-03
*** 
*** Revision History
*** Date		Author			Description
*** 2009-03-03	tl				Created
*************************************************************************************/</span>
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">FUNCTION</span> <span style="color: #66cc66;">&#91;</span>dbo<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">.</span><span style="color: #66cc66;">&#91;</span>Utility_GetAgentJobStatus_F01<span style="color: #66cc66;">&#93;</span> 
<span style="color: #66cc66;">&#40;</span>
	@JobName varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>
RETURNS @JobStatus <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>JobStatus<span style="color: #66cc66;">&#93;</span> BIT<span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">AS</span>
BEGIN
&nbsp;
	<span style="color: #993333; font-weight: bold;">WITH</span> JobActivity <span style="color: #993333; font-weight: bold;">AS</span>
	<span style="color: #66cc66;">&#40;</span>
	<span style="color: #993333; font-weight: bold;">SELECT</span> 
		 a<span style="color: #66cc66;">.</span>start_execution_date
		<span style="color: #66cc66;">,</span>a<span style="color: #66cc66;">.</span>stop_execution_date
		<span style="color: #66cc66;">,</span>ROW_NUMBER<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> OVER <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> session_id <span style="color: #993333; font-weight: bold;">DESC</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#91;</span>RowNumber<span style="color: #66cc66;">&#93;</span>
	<span style="color: #993333; font-weight: bold;">FROM</span>
		msdb<span style="color: #66cc66;">.</span>dbo<span style="color: #66cc66;">.</span>sysjobactivity a <span style="color: #993333; font-weight: bold;">WITH</span><span style="color: #66cc66;">&#40;</span>NOLOCK<span style="color: #66cc66;">&#41;</span>
		<span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span> msdb<span style="color: #66cc66;">.</span>dbo<span style="color: #66cc66;">.</span>sysjobs b <span style="color: #993333; font-weight: bold;">WITH</span><span style="color: #66cc66;">&#40;</span>NOLOCK<span style="color: #66cc66;">&#41;</span>
		   <span style="color: #993333; font-weight: bold;">ON</span> 
			a<span style="color: #66cc66;">.</span><span style="color: #66cc66;">&#91;</span>job_id<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> b<span style="color: #66cc66;">.</span><span style="color: #66cc66;">&#91;</span>job_id<span style="color: #66cc66;">&#93;</span>
			<span style="color: #993333; font-weight: bold;">AND</span> b<span style="color: #66cc66;">.</span><span style="color: #66cc66;">&#91;</span>name<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> @JobName
	<span style="color: #66cc66;">&#41;</span>
	<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> @JobStatus
	<span style="color: #993333; font-weight: bold;">SELECT</span> COUNT<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>
	<span style="color: #993333; font-weight: bold;">FROM</span> JobActivity
	<span style="color: #993333; font-weight: bold;">WHERE</span>
		start_execution_date <span style="color: #993333; font-weight: bold;">IS</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>
		<span style="color: #993333; font-weight: bold;">AND</span> stop_execution_date <span style="color: #993333; font-weight: bold;">IS</span> <span style="color: #993333; font-weight: bold;">NULL</span>
		<span style="color: #993333; font-weight: bold;">AND</span> RowNumber <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span>
&nbsp;
	<span style="color: #993333; font-weight: bold;">RETURN</span>
END</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://timlaqua.com/2009/05/a-cleaner-way-to-detect-the-state-of-a-sql-server-agent-job-in-sql-server-2005/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL Server Analysis Services Command (XMLA) Agent Job Step Reports Success On Command Failure</title>
		<link>http://timlaqua.com/2009/03/sql-server-analysis-services-command-xmla-agent-job-step-reports-success-on-command-failure/</link>
		<comments>http://timlaqua.com/2009/03/sql-server-analysis-services-command-xmla-agent-job-step-reports-success-on-command-failure/#comments</comments>
		<pubDate>Sat, 07 Mar 2009 20:35:11 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Scripts & Code]]></category>
		<category><![CDATA[agent job]]></category>
		<category><![CDATA[analysis services]]></category>
		<category><![CDATA[business intelligence]]></category>
		<category><![CDATA[cube processing]]></category>
		<category><![CDATA[job failure]]></category>
		<category><![CDATA[sql server 2005]]></category>
		<category><![CDATA[t-sql]]></category>
		<category><![CDATA[workaround]]></category>
		<category><![CDATA[xmla]]></category>

		<guid isPermaLink="false">http://timlaqua.com/?p=65</guid>
		<description><![CDATA[I ran in to this the other day, did some googling, and really did not like what I saw for workarounds. In SQL Server 2005, when an XMLA job step fails (returns an Exception node in the XML response), the job step still reports success (because it's defining success as "did I get a response") [...]]]></description>
			<content:encoded><![CDATA[<p>I ran in to this the other day, did some googling, and really did not like what I saw for workarounds.  In SQL Server 2005, when an XMLA job step fails (returns an Exception node in the XML response), the job step still reports success (because it's defining success as "did I get a response") - this has been fixed in SQL Server 2008.  Common workarounds are using ascmd.exe or SSIS to handle the XMLA commands (ish - both of those solutions add a lot of complexity for a simple problem).  So, I came up with a workaround that checks the text of the previous job step for the substring "&lt;Exception ".  It's been working thus far, with no issues.</p>
<p>After each XMLA command step, insert a T-SQL step to verify that the XMLA command step succeeded:</p>

<div class="wp_syntax"><div class="code"><pre class="tsql" style="font-family:monospace;"><span style="color: #0000FF;">DECLARE</span> @JobName <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">64</span><span style="color: #808080;">&#41;</span>
&nbsp;
<span style="color: #0000FF;">SET</span> @JobName <span style="color: #808080;">=</span> ‘Name <span style="color: #0000FF;">OF</span> Job This Step Belongs <span style="color: #0000FF;">TO</span>’
&nbsp;
<span style="color: #0000FF;">DECLARE</span> @Message <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1024</span><span style="color: #808080;">&#41;</span>
&nbsp;
<span style="color: #0000FF;">SELECT</span> <span style="color: #0000FF;">TOP</span> <span style="color: #000;">1</span> @Message <span style="color: #808080;">=</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#91;</span>message<span style="color: #808080;">&#93;</span> <span style="color: #0000FF;">AS</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>
<span style="color: #0000FF;">FROM</span> msdb.<span style="color: #202020;">dbo</span>.<span style="color: #202020;">sysjobhistory</span> a
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span> msdb.<span style="color: #202020;">dbo</span>.<span style="color: #202020;">sysjobs</span> b
<span style="color: #0000FF;">ON</span> a.<span style="color: #202020;">job_id</span> <span style="color: #808080;">=</span> b.<span style="color: #202020;">job_id</span> <span style="color: #808080;">AND</span> b.<span style="color: #808080;">&#91;</span>NAME<span style="color: #808080;">&#93;</span> <span style="color: #808080;">=</span> @JobName
<span style="color: #0000FF;">ORDER</span> <span style="color: #0000FF;">BY</span> run_date <span style="color: #0000FF;">DESC</span>, run_time <span style="color: #0000FF;">DESC</span>, step_id <span style="color: #0000FF;">DESC</span>
&nbsp;
<span style="color: #0000FF;">IF</span> @Message <span style="color: #808080;">LIKE</span> ‘<span style="color: #808080;">%&lt;</span>Exception <span style="color: #808080;">%</span>’
<span style="color: #0000FF;">RAISERROR</span> <span style="color: #808080;">&#40;</span>@Message, <span style="color: #000;">17</span>, <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span></pre></div></div>

<p><strong><em>UPDATE (2009-04-03): Added <code>, step_id DESC</code> to <code>ORDER BY</code> clause - when the XMLA job fails instantly (say you tried to process a nonexistant partition), run_time doesn't have enough granularity to sort properly.</em></strong></p>
<p>Once your done, your job steps will look something like this:</p>
<p><a href="http://timlaqua.com/wp-content/uploads/2009/03/xmla-command-verification-steps.png"><img src="http://timlaqua.com/wp-content/uploads/2009/03/xmla-command-verification-steps.png" alt="xmla-command-verification-steps" title="xmla-command-verification-steps" width="450" class="alignnone size-full wp-image-67" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://timlaqua.com/2009/03/sql-server-analysis-services-command-xmla-agent-job-step-reports-success-on-command-failure/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Locating All Checked Out Excel Documents in SharePoint (WSS 3.0)</title>
		<link>http://timlaqua.com/2008/10/locating-all-checked-out-excel-documents-in-sharepoint-wss-30/</link>
		<comments>http://timlaqua.com/2008/10/locating-all-checked-out-excel-documents-in-sharepoint-wss-30/#comments</comments>
		<pubDate>Tue, 07 Oct 2008 18:12:53 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Scripts & Code]]></category>
		<category><![CDATA[checkin]]></category>
		<category><![CDATA[checkout]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[sharepoint]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[t-sql]]></category>

		<guid isPermaLink="false">http://timlaqua.com/?p=49</guid>
		<description><![CDATA[SELECT DirName, LeafName, tp_Email, CheckoutDate, IsCheckoutToLocal FROM AllDocs d WITH&#40;nolock&#41; INNER JOIN Webs w WITH&#40;nolock&#41; ON d.WebId = w.Id INNER JOIN Sites s WITH&#40;nolock&#41; ON w.SiteId = s.Id INNER JOIN UserInfo u WITH&#40;nolock&#41; ON &#40;s.Id=u.tp_SiteID AND u.tp_ID=CheckoutUserId&#41; WHERE d.Type &#60;&#62; 1 AND &#40;LeafName LIKE '%.xls' OR LeafName LIKE '%.xlsx'&#41; AND &#40;LeafName NOT LIKE '%template%'&#41; AND [...]]]></description>
			<content:encoded><![CDATA[
<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> 
	DirName<span style="color: #66cc66;">,</span>
	LeafName<span style="color: #66cc66;">,</span>
	tp_Email<span style="color: #66cc66;">,</span> 
	CheckoutDate<span style="color: #66cc66;">,</span> 
	IsCheckoutToLocal
<span style="color: #993333; font-weight: bold;">FROM</span>     
	AllDocs d <span style="color: #993333; font-weight: bold;">WITH</span><span style="color: #66cc66;">&#40;</span>nolock<span style="color: #66cc66;">&#41;</span> 
	<span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span> Webs w <span style="color: #993333; font-weight: bold;">WITH</span><span style="color: #66cc66;">&#40;</span>nolock<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">ON</span> d<span style="color: #66cc66;">.</span>WebId <span style="color: #66cc66;">=</span> w<span style="color: #66cc66;">.</span>Id
	<span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span> Sites s <span style="color: #993333; font-weight: bold;">WITH</span><span style="color: #66cc66;">&#40;</span>nolock<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">ON</span> w<span style="color: #66cc66;">.</span>SiteId <span style="color: #66cc66;">=</span> s<span style="color: #66cc66;">.</span>Id
	<span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span> UserInfo u <span style="color: #993333; font-weight: bold;">WITH</span><span style="color: #66cc66;">&#40;</span>nolock<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">ON</span> <span style="color: #66cc66;">&#40;</span>s<span style="color: #66cc66;">.</span>Id<span style="color: #66cc66;">=</span>u<span style="color: #66cc66;">.</span>tp_SiteID <span style="color: #993333; font-weight: bold;">AND</span> u<span style="color: #66cc66;">.</span>tp_ID<span style="color: #66cc66;">=</span>CheckoutUserId<span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">WHERE</span>
	d<span style="color: #66cc66;">.</span>Type <span style="color: #66cc66;">&lt;&gt;</span> <span style="color: #cc66cc;">1</span> 
	<span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #66cc66;">&#40;</span>LeafName <span style="color: #993333; font-weight: bold;">LIKE</span> <span style="color: #ff0000;">'%.xls'</span> <span style="color: #993333; font-weight: bold;">OR</span> LeafName <span style="color: #993333; font-weight: bold;">LIKE</span> <span style="color: #ff0000;">'%.xlsx'</span><span style="color: #66cc66;">&#41;</span> 
	<span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #66cc66;">&#40;</span>LeafName <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">LIKE</span> <span style="color: #ff0000;">'%template%'</span><span style="color: #66cc66;">&#41;</span>
	<span style="color: #993333; font-weight: bold;">AND</span> DeleteTRansactionId <span style="color: #66cc66;">=</span> CAST<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span> <span style="color: #993333; font-weight: bold;">AS</span> VARBINARY<span style="color: #66cc66;">&#41;</span>
	<span style="color: #993333; font-weight: bold;">AND</span> IsCurrentVersion <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span>
	<span style="color: #993333; font-weight: bold;">AND</span> IsCheckoutToLocal <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span>
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span>
	tp_Email <span style="color: #993333; font-weight: bold;">ASC</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://timlaqua.com/2008/10/locating-all-checked-out-excel-documents-in-sharepoint-wss-30/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
