<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title />
	
	<link>http://nelsonsweb.net</link>
	<description />
	<lastBuildDate>Tue, 12 Feb 2013 15:30:21 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Nelsonswebnet" /><feedburner:info uri="nelsonswebnet" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>Nelsonswebnet</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Powershell: delete files older than X days</title>
		<link>http://feedproxy.google.com/~r/Nelsonswebnet/~3/wrmy7f7FNXU/</link>
		<comments>http://nelsonsweb.net/2013/02/powershell-delete-files-older-than-x-days/#comments</comments>
		<pubDate>Tue, 12 Feb 2013 15:30:21 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[TSQL2sday]]></category>
		<category><![CDATA[powershell]]></category>

		<guid isPermaLink="false">http://nelsonsweb.net/?p=301</guid>
		<description><![CDATA[On a recent project, I needed to delete archive folders that were older than a specified number of days. The thing that made this a little more challenging is that there were Daily, Weekly, and Monthly folders (similar to the screenshot below); each of which had a different retention period. I found several scripts to <a href='http://nelsonsweb.net/2013/02/powershell-delete-files-older-than-x-days/' class='excerpt-more'>[Keep reading...]</a>]]></description>
				<content:encoded><![CDATA[<p>On a recent project, I needed to delete archive folders that were older than a specified number of days.  The thing that made this a little more challenging is that there were Daily, Weekly, and Monthly folders (similar to the screenshot below); each of which had a different retention period.<br />
<a href="http://nelsonsweb.net/wp-content/uploads/2013/02/folder-list.png"><img src="http://nelsonsweb.net/wp-content/uploads/2013/02/folder-list-188x300.png" alt="" title="folder list" width="188" height="300" class="alignnone size-medium wp-image-309" /></a><br />
I found several scripts to delete folders and files older than a specified number of days, but these scripts would delete all the contents of the specified folder.  I needed to be able to filter out the Daily, Weekly, or Monthly folders separately to handle their retention period.  </p>
<p>This script is can be customized.  Change the &#8220;-filter&#8221; to include the folder names that you want to delete, and change the number of days in the addDays () command.<br />
Another really handy option is to use the -whatif option at the end of the script.  This will print out in the powershell window what will be deleted, but it will not delete the files.  This will let you test the delete without actually deleting the folders/files.  The first delete example below includes the -whatif option so that you can see where it goes.</p>
<pre class="brush: powershell; title: ; notranslate">
$thedirectory = &quot;C:\test\ImportFolder\Archive&quot;
# use &quot;-whatif&quot; to show what will be deleted without actually deleting anything
cd $thedirectory
get-childitem $thedirectory -filter &quot;*daily*&quot; |? {$_.psiscontainer &amp;nbsp;-and $_.lastwritetime -le (get-date).adddays(-35)} |% {remove-item $_ -force -recurse -whatif}
get-childitem $thedirectory -filter &quot;*weekly*&quot; |? {$_.psiscontainer &amp;nbsp;-and $_.lastwritetime -le (get-date).adddays(-15)} |% {remove-item $_ -force -recurse}
get-childitem $thedirectory -filter &quot;*monthly*&quot; |? {$_.psiscontainer &amp;nbsp;-and $_.lastwritetime -le (get-date).addmonths(-25)} |% {remove-item $_ -force -recurse }
</pre>
<p><a href="http://blog.waynesheffield.com/wayne/archive/2013/02/invitation-for-t-sql-tuesday-39-can-you-shell-what-the-posh-is-cooking/"><img class="size-full wp-image-161 alignleft" title="TSQL Tuesday logo" src="http://nelsonsweb.net/wp-content/uploads/2011/09/T-SQLLogo.jpg" alt="" width="145" height="150" /></a>This post is part of the blogging phenomenon known as TSQL Tuesday. This month&#8217;s blog party is hosted by <a href="http://blog.waynesheffield.com/wayne/">Wayne Sheffield</a>, who is writing a series of blog posts in the month of February all about powershell. &nbsp;I couldn&#8217;t pick just 1 script to share today, so here is my second post on the topic for day.</p>
<img src="http://feeds.feedburner.com/~r/Nelsonswebnet/~4/wrmy7f7FNXU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://nelsonsweb.net/2013/02/powershell-delete-files-older-than-x-days/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://nelsonsweb.net/2013/02/powershell-delete-files-older-than-x-days/</feedburner:origLink></item>
		<item>
		<title>Wait for file before processing</title>
		<link>http://feedproxy.google.com/~r/Nelsonswebnet/~3/j6roYr0u8gE/</link>
		<comments>http://nelsonsweb.net/2013/02/wait-for-file-before-processing/#comments</comments>
		<pubDate>Tue, 12 Feb 2013 14:30:04 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[SSIS]]></category>
		<category><![CDATA[TSQL2sday]]></category>
		<category><![CDATA[#tsql2sday]]></category>
		<category><![CDATA[powershell]]></category>

		<guid isPermaLink="false">http://nelsonsweb.net/?p=294</guid>
		<description><![CDATA[As part of a recent project, I needed to check if a file existed before starting an SSIS package to import that file.  The catch was that I did not know what time time file was going to be placed on the file system.  If the SSIS package runs and the file does not exist <a href='http://nelsonsweb.net/2013/02/wait-for-file-before-processing/' class='excerpt-more'>[Keep reading...]</a>]]></description>
				<content:encoded><![CDATA[<p>As part of a recent project, I needed to check if a file existed before starting an SSIS package to import that file.  The catch was that I did not know what time time file was going to be placed on the file system.  If the SSIS package runs and the file does not exist yet, the package will fail.</p>
<p>You can create a script task component within SSIS to check for a file and then sleep, however several sources said that this could spike the processor so I deceded to go a different route.  To solve the problem, I wrote a quick little powershell script to check if the file exists and then wait in a loop before starting the SSIS package.</p>
<p>I created a SQL agent job with 2 steps.  The job runs daily at 1:00 AM. The job has a status of Executing on Step 1 until the file exists.</p>
<p style="padding-left: 30px;">Step 1: powershell script to check for the file (see below)</p>
<p style="padding-left: 30px;">Step 2: Execute SSIS package task.</p>
<p>The file that I am looking for in this example is: C:\test\ImportFolder\fileToCheck_20130212.txt<br />
You will notice that today&#8217;s date is also appended to the end of the file name.  I built the file name out dynamically along with the current date stamp.</p>
<pre class="brush: powershell; title: ; notranslate">
$dt = Get-Date -format yyyyMMdd
$path = 'C:\test\ImporFolder\'
$theFile = $path + 'fileToCheck_' + $dt +'.txt'

#  $theFile variable will contain:  C:\test\ImportFolder\fileToCheck_20130212.txt
While (1 -eq 1) {
	IF (Test-Path $theFile) {
		#file exists. break loop
		break
	}
	#sleep for 60 seconds, then check again
	Start-Sleep -s 60
}
</pre>
<p><a href="http://blog.waynesheffield.com/wayne/archive/2013/02/invitation-for-t-sql-tuesday-39-can-you-shell-what-the-posh-is-cooking/"><img class="size-full wp-image-161 alignleft" title="TSQL Tuesday logo" src="http://nelsonsweb.net/wp-content/uploads/2011/09/T-SQLLogo.jpg" alt="" width="145" height="150" /></a>This post is part of the blogging phenomenon known as TSQL Tuesday. This month&#8217;s blog party is hosted by <a href="http://blog.waynesheffield.com/wayne/">Wayne Sheffield</a>, who is writing a series of blog posts in the month of February all about powershell..</p>
<img src="http://feeds.feedburner.com/~r/Nelsonswebnet/~4/j6roYr0u8gE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://nelsonsweb.net/2013/02/wait-for-file-before-processing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://nelsonsweb.net/2013/02/wait-for-file-before-processing/</feedburner:origLink></item>
		<item>
		<title>SSIS execute task only on Tuesday</title>
		<link>http://feedproxy.google.com/~r/Nelsonswebnet/~3/JeISQC6-8lY/</link>
		<comments>http://nelsonsweb.net/2013/01/ssis-execute-task-only-on-tuesday/#comments</comments>
		<pubDate>Wed, 16 Jan 2013 14:30:46 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[SSIS]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://nelsonsweb.net/?p=282</guid>
		<description><![CDATA[I&#8217;ve started working with SSIS a lot more lately.  I am going to attempt to document here some of the quirks that took me a little while to figure out along the way. In this tidbit, I have a multi-step SSIS package that needs to be run on a daily basis.  However, one step of <a href='http://nelsonsweb.net/2013/01/ssis-execute-task-only-on-tuesday/' class='excerpt-more'>[Keep reading...]</a>]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve started working with SSIS a lot more lately.  I am going to attempt to document here some of the quirks that took me a little while to figure out along the way.</p>
<p>In this tidbit, I have a multi-step SSIS package that needs to be run on a daily basis.  However, one step of the process should only be run on a specific day of the week (lets say it should only be run on Tuesday).</p>
<p>My screenshots are all taken in Visual Studio 2010.  The process is the same for 2008 R2.</p>
<p>The process:</p>
<ol>
<li>Create the necessary steps.  For this simple example, I created 3 Execute SQL tasks.  They each run the query: &#8220;SELECT 1&#8243;.<br />
<a href="http://nelsonsweb.net/wp-content/uploads/2013/01/1.png"><img class="size-full wp-image-283 alignnone" title="step 1" src="http://nelsonsweb.net/wp-content/uploads/2013/01/1.png" alt="" width="284" height="203" /></a></li>
<li>Drag the green arrows to link each of the tasks in order.  By default, the links will all be success constraints.<br />
<a href="http://nelsonsweb.net/wp-content/uploads/2013/01/2.png"><img class="alignnone size-full wp-image-284" title="Step 2" src="http://nelsonsweb.net/wp-content/uploads/2013/01/2.png" alt="" width="289" height="193" /></a></li>
<li>Double click on the line between Task 1 and Task 2.  This will open the Precedence Constraint Editor.</li>
<ol>
<li>Change Evaluation operation to: &#8220;Expression and Constraint&#8221;</li>
<li>In the expression block, type: &#8220;DATEPART( &#8220;dw&#8221;, getdate()) ==3&#8243;</li>
<ul>
<li>Using the DATEPART(&#8220;dw&#8221; ) function, Sunday=1 and Saturday=7.  Since we only want Tuesday, we choose ==3.</li>
</ul>
<li>Press OK</li>
<li>You will notice that the line between Task 1 and Task 2 now has an &#8220;fx&#8221; symbol on top of it.<br />
<a href="http://nelsonsweb.net/wp-content/uploads/2013/01/3.png"><img class="alignnone size-medium wp-image-285" title="Step 3" src="http://nelsonsweb.net/wp-content/uploads/2013/01/3-300x223.png" alt="" width="300" height="223" /></a></li>
</ol>
<li>At this point, the package will run and Task 2 will only run on the specified day.  However there is an issue with the current setup: Task 3 will begin executing as soon as Task 1 completes.  It will not wait  until Task 2 completes on Tuesdays.  We need to modify that link as well to create a fork in the path.</li>
<li>Double click on the link between Task 1 and Task 3.</li>
<ol>
<li>Change Evaluation operation to: &#8220;Expression and Constraint&#8221;</li>
<li>In the expression block, type: &#8220;DATEPART( &#8220;dw&#8221;, getdate()) !=3&#8243;</li>
<li>Under multiple constraints, change to the option: &#8220;Logical OR. One constraint must evaluate to True&#8221;</li>
<ul>
<li>Changing to Logical OR is required.  Since we created the fork at Task 1, only one of the two lines going into Task 3 will evaluate as successful completion.</li>
</ul>
<li>Press OK</li>
<li>You will notice that the line between Task 1 and Task 3 turns into a dashed line and it also has an &#8220;fx&#8221; symbol on top of it.<br />
<a href="http://nelsonsweb.net/wp-content/uploads/2013/01/4.png"><img class="alignnone size-medium wp-image-286" title="Step 5" src="http://nelsonsweb.net/wp-content/uploads/2013/01/4-300x210.png" alt="" width="300" height="210" /></a></li>
</ol>
<li>You can now run your package to test that the steps work properly.  To test the design, I changed my formula&#8217;s ==3 and !=3 to a different day of the week to make sure that Task 2 got bypassed correctly on its off day.</li>
</ol>
<img src="http://feeds.feedburner.com/~r/Nelsonswebnet/~4/JeISQC6-8lY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://nelsonsweb.net/2013/01/ssis-execute-task-only-on-tuesday/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://nelsonsweb.net/2013/01/ssis-execute-task-only-on-tuesday/</feedburner:origLink></item>
		<item>
		<title>SQL Saturday Pittsburgh</title>
		<link>http://feedproxy.google.com/~r/Nelsonswebnet/~3/6iL_i28fClc/</link>
		<comments>http://nelsonsweb.net/2012/09/sql-saturday-pittsburgh/#comments</comments>
		<pubDate>Mon, 01 Oct 2012 02:02:59 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Random Thoughts]]></category>

		<guid isPermaLink="false">http://nelsonsweb.net/?p=276</guid>
		<description><![CDATA[Wow, somehow I managed to not post anything here for 6 months!  I started a new job since then, which has kept me really busy, and I did not make the time for posting anything on my blog. &#160; The big news is that Pittsburgh&#8217;s SQL Satuday is this Saturday October 6 at La Roche in <a href='http://nelsonsweb.net/2012/09/sql-saturday-pittsburgh/' class='excerpt-more'>[Keep reading...]</a>]]></description>
				<content:encoded><![CDATA[<p>Wow, somehow I managed to not post anything here for 6 months!  I started a new job since then, which has kept me really busy, and I did not make the time for posting anything on my blog.</p>
<p>&nbsp;</p>
<p><a href="http://nelsonsweb.net/wp-content/uploads/2012/09/sqlsat171_web.png"><img class="alignleft size-full wp-image-277" title="sqlsat171_web" src="http://nelsonsweb.net/wp-content/uploads/2012/09/sqlsat171_web.png" alt="" width="236" height="115" /></a>The big news is that <a href="http://sqlsaturday.com/171/eventhome.aspx">Pittsburgh&#8217;s SQL Satuday</a> is this Saturday October 6 at La Roche in the north hills of Pittsburgh.  I have been organizing the schedule for the event, which is now posted on the SQL Saturday site. Check it out, and make sure you get registered to attend.  There&#8217;s a great mix of local and out of town speakers, and some great topics that will be presented.</p>
<p>Let me know if you have any questions, and hope to see you on Saturday!</p>
<img src="http://feeds.feedburner.com/~r/Nelsonswebnet/~4/6iL_i28fClc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://nelsonsweb.net/2012/09/sql-saturday-pittsburgh/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://nelsonsweb.net/2012/09/sql-saturday-pittsburgh/</feedburner:origLink></item>
		<item>
		<title>Import Active Directory users into SQL Server</title>
		<link>http://feedproxy.google.com/~r/Nelsonswebnet/~3/3su-Hy6_M3g/</link>
		<comments>http://nelsonsweb.net/2012/03/import-active-directory-users-into-sql-server/#comments</comments>
		<pubDate>Wed, 21 Mar 2012 17:31:14 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[ActiveDirectory]]></category>
		<category><![CDATA[powershell]]></category>

		<guid isPermaLink="false">http://nelsonsweb.net/?p=240</guid>
		<description><![CDATA[I needed to import a list of all Active Directory user accounts into a table in SQL Server for a recent project. This project also gave me a perfect opportunity to learn a little bit of powershell. Below chronicles the script that I built. I’m going to skip over a lot of the powershell basics <a href='http://nelsonsweb.net/2012/03/import-active-directory-users-into-sql-server/' class='excerpt-more'>[Keep reading...]</a>]]></description>
				<content:encoded><![CDATA[<p>I needed to import a list of all Active Directory user accounts into a table in SQL Server for a recent project. This project also gave me a perfect opportunity to learn a little bit of powershell. Below chronicles the script that I built. I’m going to skip over a lot of the powershell basics information, as that is available from other sources. For this project, I needed to populate a table with these fields from Active Directory: Display Name, NT username, email address, and office phone.<br />
I used the powershell Get-ADUser cmdlet to get the information out of Active Directory<br />
Before doing anything else, you need to open a powershell command window (Start&#8211;&gt;Run&#8211;&gt;powershell.exe) and import the Powershell ActiveDirectory module:</p>
<pre class="brush: powershell; title: ; notranslate">
PS C:\&gt; Import-Module activedirectory
</pre>
<p>After importing the module, you can learn more about the Get-ADUser cmdlet by using some of these commands</p>
<pre class="brush: powershell; title: ; notranslate">
Get-Help Get-ADUser
Get-Help Get-ADUser -examples
Get-Help Get-ADUser -detailed
</pre>
<p>Examples are great, but I learn better by seeing real results, so lets run a quick query to see what information we get.</p>
<pre class="brush: powershell; title: ; notranslate">
Get-ADUser -filter * -ResultSetSize 1
#Note, I included “-ResultSetSize 1” so that I was not overwhelming the domain controllers while testing.
</pre>
<p>Awesome, I can now see user accounts from Active Directory! The output that I got showed me some of the information that I needed, but I am still missing some pieces (primarily email address and phone number). The “-Properties” option will let you pick additional fields to include in the output. I got a little stuck here briefly, because the Get-ADUser cmdlet names for the properties do not all match the Active Directory field names. To figure out what the appropriate field names were, I ran this:</p>
<pre class="brush: powershell; title: ; notranslate">
Get-ADUser -filter * -ResultSetSize 1 -Properties *
</pre>
<p>Cool, now I can put the fields together to get a shortened list of only what I am looking for:</p>
<pre class="brush: powershell; title: ; notranslate">
Get-ADUser -filter * -ResultSetSize 1 -Properties EmailAddress,OfficePhone
# Note this will return additional fields (DistinguishedName,Enabled,ObjectClass, SID,…)
</pre>
<p>I got a little bit stuck here too, because I was getting too much information. When I got to the point of exporting this data to a CSV file and importing it into SQL Server (coming later), I got hung up because some of the fields did not always have information for my organization. The solution came by using a pipe (SHIFT + \ key) and the Select-Object cmdlet. This let me filter for only the specific columns that I wanted out of Active Directory.</p>
<pre class="brush: powershell; title: ; notranslate">
Get-ADUser -filter * -ResultSetSize 1 -Properties EmailAddress,OfficePhone | Select-Object EmailAddress,OfficePhone,DisplayName,SamAccountName
</pre>
<p>I now see only the 4 columns that I care about. On a larger scale test, I realized that I was returning accounts that I did not want to see (like disabled accounts, Administrative accounts, etc.) I used the –Filter option to include some search criteria here.<br />
Filtering in powershell is a little different than what I am used to. For example, “=” is “-eq” in powershell and “not equal to” or “&lt;&gt;” is “-notlike” in powershell. You can also combine multiple filters by including the entire set in curly brackets { }, individual parameters in parenthesis (), and using the “-and” operator. The Asterisk is the wildcard variable.<br />
For example:</p>
<pre class="brush: powershell; title: ; notranslate">
-Filter {(Name -notlike &quot;*(Administrator)&quot;) -and (Name -notlike &quot;Matt*&quot;) -and (Enabled -eq &quot;True&quot;) }
# I also threw in there where Name is not like Matt*
</pre>
<p>Now that I have only the fields that I want, and I filtered out the users that I don’t want to see, I can start working on importing it into SQL Server. I could have used powershell to insert the records directly into SQL, but I was concerned about latency issues and spamming the domain controllers into a denial-of-service attack. I was working with more than 50,000 Active Directory accounts. I definitely did not want to hold up the domain controllers if there was an issue with the SQL server during the process. Because of this, I decided to export the data as a CSV comma delimited file and then use SSIS to import the data.<br />
Exporting the data to a csv file uses another pipe (SHIFT + \ key) and the export-csv cmdlet. Make sure to put in your appropriate file path to export to</p>
<pre class="brush: powershell; title: ; notranslate">
#Make sure you put your file path between the &lt; &gt;
 | export-csv -path \\\\ADUsersExported.csv -NoTypeInformation -Encoding &quot;UTF8&quot;
</pre>
<h4><span style="text-decoration: underline;">Putting everything together.</span></h4>
<p>Make sure to put in your appropriate file path to export to.<br />
I also took out the “-ResultSetSize” option so that all records were returned.</p>
<pre class="brush: powershell; title: ; notranslate">
#Make sure you put your file path between the &lt; &gt;
Get-ADUser -Filter {(Name -notlike &quot;*(Administrator)&quot;)  -and (Enabled -eq &quot;True&quot;) }  -Properties SamAccountName,DisplayName,EmailAddress,OfficePhone | Select-Object EmailAddress,OfficePhone,DisplayName,SamAccountName | export-csv -path \\\\ADUsersExported.csv -NoTypeInformation -Encoding &quot;UTF8&quot;
</pre>
<p>Once the data was exported to a CSV comma delimited file, I am using SSIS to import it into SQL server. The powershell script and SSIS package are both scheduled to run daily overnight when things should be slower on the servers.</p>
<img src="http://feeds.feedburner.com/~r/Nelsonswebnet/~4/3su-Hy6_M3g" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://nelsonsweb.net/2012/03/import-active-directory-users-into-sql-server/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://nelsonsweb.net/2012/03/import-active-directory-users-into-sql-server/</feedburner:origLink></item>
		<item>
		<title>SQL Tuesday #028 – Jack of All Trades, Master of None</title>
		<link>http://feedproxy.google.com/~r/Nelsonswebnet/~3/CIfKz862Z9k/</link>
		<comments>http://nelsonsweb.net/2012/03/jack-of-all-trades-master-of-none/#comments</comments>
		<pubDate>Tue, 13 Mar 2012 15:00:32 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[TSQL2sday]]></category>
		<category><![CDATA[#tsql2sday]]></category>

		<guid isPermaLink="false">http://nelsonsweb.net/?p=242</guid>
		<description><![CDATA[This month&#8217;s TSQL Tuesday is hosted by Argenis Fernandez.  This month&#8217;s topic:  &#8221;blog about your experience. Tell us why you specialized, or why you’d like to specialize. If you don’t think that specialization is a good thing, tell us why. Discuss. Argue your point(s).&#8221; ================================================= My first job out of college was a Network Administrator for <a href='http://nelsonsweb.net/2012/03/jack-of-all-trades-master-of-none/' class='excerpt-more'>[Keep reading...]</a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://sqlblog.com/blogs/argenis_fernandez/archive/2012/03/05/t-sql-tuesday-028-jack-of-all-trades-master-of-none.aspx"><img class="alignleft size-full wp-image-161" title="TSQL Tuesday logo" src="http://nelsonsweb.net/wp-content/uploads/2011/09/T-SQLLogo.jpg" alt="" width="145" height="150" /></a>This month&#8217;s <a href="http://sqlblog.com/blogs/argenis_fernandez/archive/2012/03/05/t-sql-tuesday-028-jack-of-all-trades-master-of-none.aspx">TSQL Tuesday</a> is hosted by Argenis Fernandez.  This month&#8217;s topic:  &#8221;blog about your experience. Tell us why you specialized, or why you’d like to specialize. If you don’t think that specialization is a good thing, tell us why. Discuss. Argue your point(s).&#8221;</p>
<p>=================================================</p>
<p>My first job out of college was a Network Administrator for a small non-profit organization.  As the only IT guy in the organization, I was responsible for a lot&#8230;managing servers, planning upgrades, scheduling downtime, email setup/support, network switches, cabling, wireless network access/security, managing data, backing up data, help desk support, desktop pc support, web site design, managing the phone system, building overhead paging, video surveillance system, report design and generation, unjamming printers and copiers, evaluating new applications, and developing custom applications.  The organization has classrooms spread out across the entire county.  Each classroom had various technologies from a PC, to phones, answering machines, and speaker systems.</p>
<p>I definitely could not specialize in any particular area in this position.  On any given day I could have needed to travel 60 miles round trip to fix a problem in one of the outlying classrooms and return to my office prepare data to submit for a federally mandated report.  When people asked me what I did, I would tell them my job was to fix anything that plugged into a wall.  With a non-existent budget, I had to get creative to make things work in the organization.</p>
<p>Through a series of life choices, I moved on to a new company in a new position that focused more on systems and database administration.  This position is definitely a lot more specialized than where I started.  There are now other support groups that I can refer people to for issues with PC&#8217;s, Exchange, networking, phones, etc.</p>
<p>I still think that it is important to keep up on a lot of the basics, especially with SQL server.  People like to blame the database as the problem when often times the solution is not nearly that simple.  Many problems that I encounter on a day-to-day basis are rooted in specialties not directly related to SQL server.  I may not be a specialist in networking, pc repair, or Active Directory administration, but it has been very beneficial to me to have a good working knowledge of these concepts.  There are other people responsible for fixing these things at my current company.  I can usually figure out what the problems is  and direct to the correct support groups fairly quickly with my generalist background.</p>
<img src="http://feeds.feedburner.com/~r/Nelsonswebnet/~4/CIfKz862Z9k" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://nelsonsweb.net/2012/03/jack-of-all-trades-master-of-none/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://nelsonsweb.net/2012/03/jack-of-all-trades-master-of-none/</feedburner:origLink></item>
		<item>
		<title>Running SSMS template explorer from network drive</title>
		<link>http://feedproxy.google.com/~r/Nelsonswebnet/~3/wxm5ojSHYmU/</link>
		<comments>http://nelsonsweb.net/2012/03/running-ssms-template-explorer-from-network-drive/#comments</comments>
		<pubDate>Mon, 12 Mar 2012 14:24:15 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[SSMS]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://nelsonsweb.net/?p=244</guid>
		<description><![CDATA[This is a quick one today as a follow-up to my previous post on using the SSMS Template explorer.  While I do like the convenience of using the template explorer to store frequently used scripts, one of my biggest  complaints was the fact that all the scripts are buried several directories down under the C:\users directory (windows <a href='http://nelsonsweb.net/2012/03/running-ssms-template-explorer-from-network-drive/' class='excerpt-more'>[Keep reading...]</a>]]></description>
				<content:encoded><![CDATA[<p>This is a quick one today as a follow-up to my previous post on using the <a title="SSMS Template explorer" href="http://nelsonsweb.net/2011/09/ssms-template-explorer/">SSMS Template explorer</a>.  While I do like the convenience of using the template explorer to store frequently used scripts, one of my biggest  complaints was the fact that all the scripts are buried several directories down under the C:\users directory (windows 7).</p>
<p>Carl Demelo shared <a href="http://www.sqlservercentral.com/articles/Management+Studio+(SSMS)/75955/">an awesome way to move your template directory</a> to a different directory on SQL Server Central.  This solution will only work on Windows 7 using the new shell command <span style="text-decoration: underline;">mklink</span>.</p>
<p>I tried it out to move my template directory to a network drive that gets backed up on a regular basis.  It worked perfect, thanks Carl!</p>
<img src="http://feeds.feedburner.com/~r/Nelsonswebnet/~4/wxm5ojSHYmU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://nelsonsweb.net/2012/03/running-ssms-template-explorer-from-network-drive/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://nelsonsweb.net/2012/03/running-ssms-template-explorer-from-network-drive/</feedburner:origLink></item>
		<item>
		<title>T_SQL Tuesday #25: Sharing Tricks</title>
		<link>http://feedproxy.google.com/~r/Nelsonswebnet/~3/6bqtLMoPZPw/</link>
		<comments>http://nelsonsweb.net/2011/12/t_sql-tuesday-25-sharing-tricks/#comments</comments>
		<pubDate>Tue, 13 Dec 2011 15:00:38 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[TSQL2sday]]></category>
		<category><![CDATA[#tsql2sday]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://nelsonsweb.net/?p=227</guid>
		<description><![CDATA[The topic for this month’s TSQL Tuesday, hosted by Allen White, is an invitation to share your tricks.  Before I get into my trick to share, I wanted to mention that Allen is a pretty awesome speaker too.  I got to see his session “Gather SQL Server Performance Data with Powershell” at the SQL Saturday <a href='http://nelsonsweb.net/2011/12/t_sql-tuesday-25-sharing-tricks/' class='excerpt-more'>[Keep reading...]</a>]]></description>
				<content:encoded><![CDATA[<p>The topic for this month’s TSQL Tuesday, hosted by Allen White, <a href="http://sqlblog.com/blogs/allen_white/archive/2011/12/05/t-sql-tuesday-025-invitation-to-share-your-tricks.aspx">is an invitation to share your tricks</a>.  Before I get into my trick to share, I wanted to mention that Allen is a pretty awesome speaker too.  I got to see his session “Gather SQL Server Performance Data with Powershell” at the SQL Saturday in Columbus earlier this year.  Allen is really excited about SQL Server and the cool things you can do with Powershell.</p>
<p>Now for my trick, I have a view that was created to help write more dynamic rolling sql queries and reports in my organization.  I’m not sure who the original author of the script is, as it has been passed around and modified several times.  I thought I would share it here in the hopes that it helps someone else someday.  If you’re the original author or know who is, please let me know so I can give you due credit.</p>
<p>This view defines a bunch of different date parameters compared to the current date, including:</p>
<ul>
<li>TODAY_BEGIN</li>
<li>TODAY_END</li>
<li>YESTERDAY_BEGIN</li>
<li>YESTERDAY_END</li>
<li>DAY_BEFORE_YESTERDAY_BEGIN</li>
<li>DAY_BEFORE_YESTERDAY_END</li>
<li>SUNDAY_WEEK_BEGIN</li>
<li>SUNDAY_WEEK_END</li>
<li>MONDAY_WEEK_BEGIN</li>
<li>MONDAY_WEEK_END</li>
<li>PREVIOUS_SUNDAY_WEEK_BEGIN</li>
<li>PREVIOUS_SUNDAY_WEEK_END</li>
<li>PREVIOUS_MONDAY_WEEK_BEGIN</li>
<li>PREVIOUS_MONDAY_WEEK_END</li>
<li>MONTH_BEGIN</li>
<li>MONTH_END</li>
<li>YESTERDAYS_MONTH_BEGIN</li>
<li>YESTERDAYS_MONTH_END</li>
<li>PREVIOUS_MONTH_BEGIN</li>
<li>PREVIOUS_MONTH_END</li>
<li>SECOND_PREVIOUS_MONTH_BEGIN</li>
<li>SECOND_PREVIOUS_MONTH_END</li>
<li>THIRD_PREVIOUS_MONTH_BEGIN</li>
<li>THIRD_PREVIOUS_MONTH_END</li>
<li>FOURTH_PREVIOUS_MONTH_BEGIN</li>
<li>FOURTH_PREVIOUS_MONTH_END</li>
<li>TWELTH_PREVIOUS_MONTH_BEGIN</li>
<li>TWELTH_PREVIOUS_MONTH_END</li>
<li>PREVIOUS_SIXTH_MONDAY_WEEK_BEGIN</li>
<li>PREVIOUS_SIXTH_MONDAY_WEEK_END</li>
<li>PREVIOUS_SIXTH_SUNDAY_WEEK_BEGIN</li>
<li>PREVIOUS_SIXTH_SUNDAY_WEEK_END</li>
<li>NEXT_MONTH_BEGIN</li>
<li>NEXT_MONTH_END</li>
</ul>
<p>You can take a quick look at the result returned from this view.  After creating the view (script included below), run:</p>
<pre class="brush: sql; title: ; notranslate">
SELECT  *
FROM    vw_date_ranges
</pre>
<p>With these columns defined, you can easily query a database table looking for rows based off of a date by cross joining this view and the adding the date columns to the where clause.  For example, if you want to see all orders for “This Week”, you can run a query similar to:</p>
<pre class="brush: sql; title: ; notranslate">
SELECT SalesOrderID,
       OrderDate,
       SalesOrderNumber,
       PurchaseOrderNumber,
       CustomerID,
       TotalDue
FROM   Sales.SalesOrderHeader
       CROSS JOIN vw_date_ranges
WHERE  Sales.SalesOrderHeader.OrderDate &gt; vw_date_ranges.SUNDAY_WEEK_BEGIN
</pre>
<p>Or if you want to see all orders for &#8220;Last Month&#8221;, you can run a query similar to:</p>
<pre class="brush: sql; title: ; notranslate">
SELECT SalesOrderID,
       OrderDate,
       SalesOrderNumber,
       PurchaseOrderNumber,
       CustomerID,
       TotalDue
FROM   Sales.SalesOrderHeader
       CROSS JOIN vw_date_ranges
WHERE  Sales.SalesOrderHeader.OrderDate &gt;= vw_date_ranges.PREVIOUS_MONTH_BEGIN
       AND Sales.SalesOrderHeader.OrderDate &lt; vw_date_ranges.MONTH_BEGIN
</pre>
<p>Using this method helps me keep my sql query clean, and provides a rolling date range on queries and reports.</p>
<p><a href="http://nelsonsweb.net/wp-content/uploads/2011/12/vw_date_ranges.zip">Download the script here</a></p>
<pre class="brush: sql; title: ; notranslate">

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE VIEW [dbo].[vw_date_ranges]
(TODAY_BEGIN, TODAY_END, YESTERDAY_BEGIN, YESTERDAY_END, DAY_BEFORE_YESTERDAY_BEGIN,
DAY_BEFORE_YESTERDAY_END, SUNDAY_WEEK_BEGIN, SUNDAY_WEEK_END, MONDAY_WEEK_BEGIN, MONDAY_WEEK_END,
PREVIOUS_SUNDAY_WEEK_BEGIN, PREVIOUS_SUNDAY_WEEK_END, PREVIOUS_MONDAY_WEEK_BEGIN, PREVIOUS_MONDAY_WEEK_END, MONTH_BEGIN,
MONTH_END, YESTERDAYS_MONTH_BEGIN, YESTERDAYS_MONTH_END, PREVIOUS_MONTH_BEGIN, PREVIOUS_MONTH_END,
SECOND_PREVIOUS_MONTH_BEGIN, SECOND_PREVIOUS_MONTH_END, THIRD_PREVIOUS_MONTH_BEGIN, THIRD_PREVIOUS_MONTH_END, FOURTH_PREVIOUS_MONTH_BEGIN,
FOURTH_PREVIOUS_MONTH_END, TWELTH_PREVIOUS_MONTH_BEGIN, TWELTH_PREVIOUS_MONTH_END, PREVIOUS_SIXTH_MONDAY_WEEK_BEGIN, PREVIOUS_SIXTH_MONDAY_WEEK_END,
PREVIOUS_SIXTH_SUNDAY_WEEK_BEGIN, PREVIOUS_SIXTH_SUNDAY_WEEK_END,NEXT_MONTH_BEGIN,NEXT_MONTH_END)
AS
select DATEADD(dd, DATEDIFF(dd,0,getdate()), 0)                                TODAY_BEGIN,
dateadd(ms,-3,DATEADD(dd, DATEDIFF(dd,0,getdate()+ 1 ), 0)) - .000011574        TODAY_END,
DATEADD(dd, DATEDIFF(dd,0,getdate()), -1)                                       YESTERDAY_BEGIN,
dateadd(ms,-3,DATEADD(dd, DATEDIFF(dd,0,getdate()  ), 0)) - .000011574          YESTERDAY_END,
DATEADD(dd, DATEDIFF(dd,0,getdate()), -2)                                       DAY_BEFORE_YESTERDAY_BEGIN,
dateadd(ms,-3,DATEADD(dd, DATEDIFF(dd,0,getdate()  ), -1)) - .000011574         DAY_BEFORE_YESTERDAY_END,
-- Relative Dates - Weeks
DATEADD(wk, DATEDIFF(wk,0,getdate()), -1)                        SUNDAY_WEEK_BEGIN,
DATEADD(wk, DATEDIFF(wk,0,getdate()), -1) + 6.999988426          SUNDAY_WEEK_END,
DATEADD(wk, DATEDIFF(wk,0,getdate()), 0)                         MONDAY_WEEK_BEGIN,
DATEADD(wk, DATEDIFF(wk,0,getdate()), 0)  + 7.999988426          MONDAY_WEEK_END,
DATEADD(wk, DATEDIFF(wk,0,getdate()), -8)                        PREVIOUS_SUNDAY_WEEK_BEGIN,
DATEADD(wk, DATEDIFF(wk,0,getdate()), -8) + 6.999988426          PREVIOUS_SUNDAY_WEEK_END,
DATEADD(wk, DATEDIFF(wk,0,getdate()), -7)                        PREVIOUS_MONDAY_WEEK_BEGIN,
DATEADD(wk, DATEDIFF(wk,0,getdate()), -7) + 7.999988426          PREVIOUS_MONDAY_WEEK_END,
-- Relative Dates - Months
dateadd(mm,datediff(mm,0,getdate()),0)                                                    MONTH_BEGIN,
dateadd(ms,-3,DATEADD(mm, DATEDIFF(m,0,getdate()  )+1, 0)) - .000011574                   MONTH_END,
dateadd(mm,datediff(mm,0,getdate() - 1),0)                                                YESTERDAYS_MONTH_BEGIN,
dateadd(ms,-3,DATEADD(mm, DATEDIFF(m,0,getdate() - 1 )+1, 0)) - .000011574                YESTERDAYS_MONTH_END,
DATEADD(mm, DATEDIFF(mm,0,getdate()  )-1, 0)                                              PREVIOUS_MONTH_BEGIN,
dateadd(ms,-3,DATEADD(mm, DATEDIFF(mm,0,getdate()  ), 0)) - .000011574                    PREVIOUS_MONTH_END,
DATEADD(mm, DATEDIFF(mm,0,getdate()  )-2, 0)                                              SECOND_PREVIOUS_MONTH_BEGIN,
dateadd(ms,-3,DATEADD(mm, DATEDIFF(mm,0,getdate()  )-1, 0)) - .000011574                  SECOND_PREVIOUS_MONTH_END,
DATEADD(mm, DATEDIFF(mm,0,getdate()  )-3, 0)                                              THIRD_PREVIOUS_MONTH_BEGIN,
dateadd(ms,-3,DATEADD(mm, DATEDIFF(mm,0,getdate()  )-2, 0)) - .000011574                  THIRD_PREVIOUS_MONTH_END,
DATEADD(mm, DATEDIFF(mm,0,getdate()  )-4, 0)                                              FOURTH_PREVIOUS_MONTH_BEGIN,
dateadd(ms,-3,DATEADD(mm, DATEDIFF(mm,0,getdate()  )-3, 0)) - .000011574                  FOURTH_PREVIOUS_MONTH_END,
DATEADD(mm, DATEDIFF(mm,0,getdate()  )-12, 0)                                              TWELTH_PREVIOUS_MONTH_BEGIN,
dateadd(ms,-3,DATEADD(mm, DATEDIFF(mm,0,getdate()  )-11, 0)) - .000011574                  TWELTH_PREVIOUS_MONTH_END,
-- Added 2/23/09 These will be used in a claim audit report that looks at data from 6 weeks prior.
DATEADD(wk, DATEDIFF(wk,0,getdate()  )-6, 0)  as   PREVIOUS_SIXTH_MONDAY_WEEK_BEGIN,
DATEADD(wk, DATEDIFF(wk,0,getdate()  )-6, 0) + 7.999988426  as PREVIOUS_SIXTH_MONDAY_WEEK_END,
DATEADD(wk, DATEDIFF(wk,0,getdate()  )-6, -1) as   PREVIOUS_SIXTH_SUNDAY_WEEK_BEGIN,
DATEADD(wk, DATEDIFF(wk,0,getdate()  )-6, -1) + 6.999988426  as PREVIOUS_SIXTH_SUNDAY_WEEK_END,
DATEADD(mm, DATEDIFF(mm,0,getdate()  )+1, 0)                                              NEXT_MONTH_BEGIN,
dateadd(ms,-3,DATEADD(mm, DATEDIFF(mm,0,getdate()  )+2, 0)) + .000011574                    NEXT_MONTH_END

</pre>
<img src="http://feeds.feedburner.com/~r/Nelsonswebnet/~4/6bqtLMoPZPw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://nelsonsweb.net/2011/12/t_sql-tuesday-25-sharing-tricks/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://nelsonsweb.net/2011/12/t_sql-tuesday-25-sharing-tricks/</feedburner:origLink></item>
		<item>
		<title>Fixing orphaned users</title>
		<link>http://feedproxy.google.com/~r/Nelsonswebnet/~3/OOuEJVjwyX4/</link>
		<comments>http://nelsonsweb.net/2011/10/fixing-orphaned-users/#comments</comments>
		<pubDate>Tue, 18 Oct 2011 14:00:52 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Fixes]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[tsql]]></category>

		<guid isPermaLink="false">http://nelsonsweb.net/?p=215</guid>
		<description><![CDATA[Whenever I restore a production database to a development server, I often end up with orphaned users. You can see in the screen shot below that username matt has no login associated with it. An account becomes orphaned when there is a user account with security rights in the database that is not linked to <a href='http://nelsonsweb.net/2011/10/fixing-orphaned-users/' class='excerpt-more'>[Keep reading...]</a>]]></description>
				<content:encoded><![CDATA[<p>Whenever I restore a production database to a development server, I often end up with orphaned users. You can see in the screen shot below that username <span style="text-decoration: underline;"><strong>matt</strong></span> has no login associated with it.</p>
<p><a href="http://nelsonsweb.net/wp-content/uploads/2011/10/orphaned1.png"><img class="size-full wp-image-219 alignnone" title="orphaned1" src="http://nelsonsweb.net/wp-content/uploads/2011/10/orphaned1.png" alt="" width="704" height="237" /></a></p>
<p>An account becomes orphaned when there is a user account with security rights in the database that is not linked to a user account that can log in to the server.  This happens because SQL logins with the same username have different SID&#8217;s on different servers.  It is not a problem for Active Directory logins because the SID is stored in Active Directory.</p>
<p>Once an account becomes orphaned, it is a pretty easy fix:</p>
<pre class="brush: sql; title: ; notranslate">
USE &lt;database name&gt;
ALTER USER &lt;username&gt; WITH LOGIN = &lt;username&gt;
</pre>
<p>But it&#8217;s still a pain to remember to run this code to reset the logins.  I usually forget, and the scratch my head for a minute to figure out why the application won&#8217;t connect to the development database anymore.</p>
<h4><span style="text-decoration: underline;">Fix it once and for all</span></h4>
<p>Microsoft has a handy script to fix orphaned users (<a href="http://support.microsoft.com/kb/918992">link</a>).  Download and run the script on your production server to create two stored procedures: sp_hexadecimal and sp_help_revlogin.</p>
<p>Then run:</p>
<pre class="brush: sql; title: ; notranslate">
EXEC sp_help_revlogin
</pre>
<p>Run the output from this procedure against your development server to create the appropriate logins with the correct username/password and SID.</p>
<p>Ever since I ran this, I have not had any more orphaned users when restoring databases back to dev.</p>
<img src="http://feeds.feedburner.com/~r/Nelsonswebnet/~4/OOuEJVjwyX4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://nelsonsweb.net/2011/10/fixing-orphaned-users/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://nelsonsweb.net/2011/10/fixing-orphaned-users/</feedburner:origLink></item>
		<item>
		<title>T-SQL Tuesday #23: Fixing Joined Views</title>
		<link>http://feedproxy.google.com/~r/Nelsonswebnet/~3/QaepGUqfbZU/</link>
		<comments>http://nelsonsweb.net/2011/10/t-sql-tuesday-23-joins/#comments</comments>
		<pubDate>Tue, 04 Oct 2011 13:00:29 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[TSQL2sday]]></category>
		<category><![CDATA[#tsql2sday]]></category>

		<guid isPermaLink="false">http://nelsonsweb.net/?p=184</guid>
		<description><![CDATA[This month&#8217;s TSQL Tuesday topic, hosted by Stuart Ainsworth, is Joins.  I am going to share a story of a performance improvement that I made with joined views. One of the main vendor-built applications that I support has views built on top of tables.  Unfortunately that&#8217;s not the end of the story.  These views are <a href='http://nelsonsweb.net/2011/10/t-sql-tuesday-23-joins/' class='excerpt-more'>[Keep reading...]</a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://codegumbo.com/index.php/2011/09/27/tsql2sday-t-sql-tuesday-23early-edition/"><img class="alignleft size-full wp-image-161" title="TSQL Tuesday logo" src="http://nelsonsweb.net/wp-content/uploads/2011/09/T-SQLLogo.jpg" alt="" width="145" height="150" /></a>This month&#8217;s TSQL Tuesday topic, hosted by Stuart Ainsworth, is Joins.  I am going to share a story of a performance improvement that I made with joined views.</p>
<p>One of the main vendor-built applications that I support has views built on top of tables.  Unfortunately that&#8217;s not the end of the story.  These views are built on top of views, which join together other views, which link back to the database tables.  In all the training materials provided by the vendor, they say to *always* use the views when writing a report on the data and never directly query the table.</p>
<p>Using the vendor provided views generally works out OK and performs reasonably well.  One particular report I wrote kept bugging me due to how long it took to run (several minutes each time). compared to how much data was actually returned.  So I started looking at the execution times and the query plans.  Note, I took the screenshots below using the fantastic free tool from SQL Sentry, <a href="http://www.sqlsentry.com/plan-explorer/sql-server-query-view.asp">SQL Sentry Plan Explorer</a>.</p>
<p>This report needed to join 5 tables to get the data that I needed.  Using the vendor provided views, here is the join diagram I started out with:</p>
<p><a href="http://nelsonsweb.net/wp-content/uploads/2011/09/join1.png"><img class="size-large wp-image-185 alignnone" title="join1" src="http://nelsonsweb.net/wp-content/uploads/2011/09/join1-1024x323.png" alt="" width="695" height="219" /></a></p>
<p>You can see that the vendor views are joining together a lot more hidden tables (table &amp; field names blurred to protect the innocent) than the 5 I actually need.  The nested views are even hitting the same tables more than once.</p>
<p>Here is the original query plan:</p>
<p><a href="http://nelsonsweb.net/wp-content/uploads/2011/09/plan1.png"><img class="size-large wp-image-186 alignnone" title="plan1" src="http://nelsonsweb.net/wp-content/uploads/2011/09/plan1-1024x493.png" alt="" width="695" height="334" /></a></p>
<p>You can&#8217;t see it in the screen shot, but one of the thick lines in the middle is representing 23 million rows!</p>
<p>OK, time to pull out the detective hat.  I decided to rewrite the query using only the base tables.  I had to do a bit of extra work with things like UTC datetime vs. local time which the views converted.  After the rewrite, the join diagram looked like this:</p>
<p><a href="http://nelsonsweb.net/wp-content/uploads/2011/10/join2.png"><img class="size-full wp-image-189 alignnone" title="join2" src="http://nelsonsweb.net/wp-content/uploads/2011/10/join2.png" alt="" width="550" height="176" /></a></p>
<p>Here is the final query plan:</p>
<p><a href="http://nelsonsweb.net/wp-content/uploads/2011/10/plan2.png"><img class="size-large wp-image-190 alignnone" title="plan2" src="http://nelsonsweb.net/wp-content/uploads/2011/10/plan2-1024x127.png" alt="" width="695" height="86" /></a></p>
<p>The highest number of rows coming through is about 11,000.  A far cry from the 23 million rows in the original query! The execution plan also looks a lot leaner than what I started with as well.</p>
<p>The original query was running with an average CPU time = 26062 ms, and an average elapsed time = 26424 ms.<br />
My rewritten query is now running with an average CPU time = 0 ms, and an average elapsed time = 266 ms.</p>
<p>Looking at the actual execution plan, SSMS is prompting me that there is a missing index for my new query, and there is still a Clustered Index Scan that accounts for 87% of the query.   I may look into that more at a later date, but for now I am very happy running a query in a couple of seconds that used to take several minutes. I don&#8217;t think it&#8217;s really worth the extra effort to try to shave another 100 ms off of a query that completes in under 300 ms.</p>
<p>The vendor supplied nested views were each joining together multiple views and tables, which was causing a lot of extra and unnecessary bloat in my query.  An hour of work and cutting out all the bloat made a huge difference in this particular report&#8217;s run time.</p>
<h3>And the users rejoice at how fast their report now runs!</h3>
<img src="http://feeds.feedburner.com/~r/Nelsonswebnet/~4/QaepGUqfbZU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://nelsonsweb.net/2011/10/t-sql-tuesday-23-joins/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://nelsonsweb.net/2011/10/t-sql-tuesday-23-joins/</feedburner:origLink></item>
	</channel>
</rss>
