<?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>Trigger Happy</title>
	<atom:link href="http://mikedefehr.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://mikedefehr.com</link>
	<description>SQL Server thoughts and observations</description>
	<lastBuildDate>Wed, 27 Jul 2011 13:32:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Finding the nth Weekday of a given month</title>
		<link>http://mikedefehr.com/2011/07/25/finding-the-nth-weekday-of-a-given-month/</link>
		<comments>http://mikedefehr.com/2011/07/25/finding-the-nth-weekday-of-a-given-month/#comments</comments>
		<pubDate>Mon, 25 Jul 2011 22:51:28 +0000</pubDate>
		<dc:creator>mdefehr</dc:creator>
				<category><![CDATA[How To]]></category>
		<category><![CDATA[Scripts]]></category>

		<guid isPermaLink="false">http://mikedefehr.com/?p=89</guid>
		<description><![CDATA[ [...]]]></description>
			<content:encoded><![CDATA[<p>[Edited from original – my colleague pointed out that the method I was using for getting the weekday returned different results depending on the DATEFIRST setting – the new solution is actually cleaner!]</p>
<p>A colleague of mine asked me for a utility to find the nth weekday of the month given a date, a number and a word such as “Wednesday”. He further challenged me to see if I could do it in one statement.</p>
<p>So for example, a call such as this:</p>
<p><code style="font-size: 12px"><span style="color: blue">SELECT </span><span style="color: black">dbo.nth_weekday_of_month_fn</span><span style="color: gray">(</span><span style="color: magenta">GETDATE</span><span style="color: gray">(),</span><span style="color: red">'Wednesday'</span><span style="color: gray">,</span><span style="color: black">3</span><span style="color: gray">)</span></code></p>
<p>When run on any day in July, 2011, will return the following:</p>
<p><code style="font-size: 12px"><span style="color: gray"><span style="color: #000000">-----------------------         <br /></span></span><span style="color: black">2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">20 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000 </span></code></p>
<p><code style="font-size: 12px"><span style="color: gray">(</span><span style="color: black">1 row</span><span style="color: gray">(</span><span style="color: black">s</span><span style="color: gray">) </span><span style="color: black">affected</span><span style="color: gray">)</span></code></p>
<p>Which is the 3rd Wednesday of this month.&#160; The date parameter serves only to identify the month (and year), so any day or time information can be ignored.&#160; It is a fairly straightforward problem, and when thought of iteratively, straightforward solutions start coming to mind – but iterative thinking is not going to solve this in a single statement.</p>
<p>From a set-based perspective, you think of the set of dates that make up the month in question, then simply choosing the right one – so the first item of business is to get a set of all the dates for the month in question.&#160; As with many solutions, this will require a numbers or tally table (simply a table with nothing but numbers in it).&#160; Many people have such a table at their disposal, but if you don’t (and you don’t need very many numbers – here we’ll only need a maximum of 31) you can use master..spt_values as discussed in a <a href="http://mikedefehr.com/2010/04/02/explanation-for-tsql-challenge-14/">previous post</a>.&#160; So starting with the first day of the month, if we add the numbers from our tally table in days, we end up with a list of days of the month (we’re clearly violating the one-statement rule, but stay tuned – we’ll bring it all together):</p>
<p><code style="font-size: 12px"><span style="color: blue">DECLARE </span><span style="color: #434343">@dt </span><span style="color: blue">DATETIME = </span><span style="color: magenta">GETDATE</span><span style="color: gray">();       <br /></span><span style="color: blue">DECLARE </span><span style="color: #434343">@dow </span><span style="color: blue">VARCHAR</span><span style="color: gray">(</span><span style="color: black">100</span><span style="color: gray">) </span><span style="color: blue">= </span><span style="color: red">'Wednesday'</span><span style="color: gray">;       <br /></span><span style="color: blue">DECLARE </span><span style="color: #434343">@num </span><span style="color: blue">INT = </span><span style="color: black">3</span><span style="color: gray">; </span></code></p>
<p><code style="font-size: 12px"><span style="color: green">--This will take off any time portion and set the value to the beginning of the month       <br /></span><span style="color: blue">SET </span><span style="color: #434343">@dt </span><span style="color: blue">= </span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">MONTH</span><span style="color: gray">,</span><span style="color: magenta">DATEDIFF</span><span style="color: gray">(</span><span style="color: magenta">MONTH</span><span style="color: gray">,</span><span style="color: black">0</span><span style="color: gray">,</span><span style="color: #434343">@dt</span><span style="color: gray">),</span><span style="color: black">0</span><span style="color: gray">); </span></code></p>
<p><code style="font-size: 12px"><span style="color: blue">SELECT </span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">DAY</span><span style="color: gray">,</span><span style="color: black">number</span><span style="color: gray">-</span><span style="color: black">1</span><span style="color: gray">,</span><span style="color: #434343">@dt</span><span style="color: gray">) </span><span style="color: blue">AS </span><span style="color: black">MonthDate       <br /></span><span style="color: blue">FROM MASTER</span><span style="color: black">..spt_values       <br /></span><span style="color: blue">WHERE </span><span style="color: black">number </span><span style="color: gray">&gt; </span><span style="color: black">0       <br />&#160;&#160;&#160; </span><span style="color: gray">AND </span><span style="color: blue">TYPE = </span><span style="color: red">'P'       <br />&#160;&#160;&#160; </span><span style="color: gray">AND </span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">DAY</span><span style="color: gray">,</span><span style="color: black">number</span><span style="color: gray">-</span><span style="color: black">1</span><span style="color: gray">,</span><span style="color: #434343">@dt</span><span style="color: gray">) &gt;= </span><span style="color: #434343">@dt       <br />&#160;&#160;&#160; </span><span style="color: gray">AND </span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">DAY</span><span style="color: gray">,</span><span style="color: black">number</span><span style="color: gray">-</span><span style="color: black">1</span><span style="color: gray">,</span><span style="color: #434343">@dt</span><span style="color: gray">) &lt; </span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">MONTH</span><span style="color: gray">,</span><span style="color: black">1</span><span style="color: gray">,</span><span style="color: #434343">@dt</span><span style="color: gray">)</span></code></p>
<p><code style="font-size: 12px"><span style="color: black">MonthDate       <br /></span><span style="color: black">-----------------------       <br /></span><span style="color: black">2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">01 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">02 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">03 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">04 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">05 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">06 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">07 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">08 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">09 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">10 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">11 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">12 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">13 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">14 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">15 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">16 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">17 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">18 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">19 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">20 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">21 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">22 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">23 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">24 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">25 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">26 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">27 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">28 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">29 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">30 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">31 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000 </span></code></p>
<p><code style="font-size: 12px"><span style="color: gray">(</span><span style="color: black">31 row</span><span style="color: gray">(</span><span style="color: black">s</span><span style="color: gray">) </span><span style="color: black">affected</span><span style="color: gray">)</span></code></p>
<p>So considering this set, we need only pull out the Wednesdays (or whatever) and count them.&#160; We can pull out the “Wednesdays” one of two ways:&#160; by using a filter with either DATENAME or DATEPART – in this case we’re expressing the weekday in “name” format so DATENAME makes the most sense – also, the number DATEPART returns depends on the DATEFIRST setting.&#160; Once we find the weekday, we can index them with a row number:</p>
<p><code style="font-size: 12px"><span style="color: black">       <br /></span><span style="color: blue">DECLARE </span><span style="color: #434343">@dt </span><span style="color: blue">DATETIME = </span><span style="color: magenta">GETDATE</span><span style="color: gray">();       <br /></span><span style="color: blue">DECLARE </span><span style="color: #434343">@dow </span><span style="color: blue">VARCHAR</span><span style="color: gray">(</span><span style="color: black">100</span><span style="color: gray">) </span><span style="color: blue">= </span><span style="color: red">'Wednesday'</span><span style="color: gray">;       <br /></span><span style="color: blue">DECLARE </span><span style="color: #434343">@num </span><span style="color: blue">INT = </span><span style="color: black">3</span><span style="color: gray">;        </p>
<p></span><span style="color: green">--This will take off any time portion and set the value to the beginning of the month       <br /></span><span style="color: blue">SET </span><span style="color: #434343">@dt </span><span style="color: blue">= </span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">MONTH</span><span style="color: gray">,</span><span style="color: magenta">DATEDIFF</span><span style="color: gray">(</span><span style="color: magenta">MONTH</span><span style="color: gray">,</span><span style="color: black">0</span><span style="color: gray">,</span><span style="color: #434343">@dt</span><span style="color: gray">),</span><span style="color: black">0</span><span style="color: gray">);        </p>
<p></span><span style="color: blue">SELECT </span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">DAY</span><span style="color: gray">,</span><span style="color: black">number</span><span style="color: gray">-</span><span style="color: black">1</span><span style="color: gray">,</span><span style="color: #434343">@dt</span><span style="color: gray">) </span><span style="color: blue">AS </span><span style="color: black">MonthDate</span><span style="color: gray">,       <br />&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: black">ROW_NUMBER</span><span style="color: gray">() </span><span style="color: blue">OVER</span><span style="color: gray">(</span><span style="color: blue">ORDER BY </span><span style="color: black">number</span><span style="color: gray">) </span><span style="color: blue">AS </span><span style="color: black">DayIndex       <br /></span><span style="color: blue">FROM MASTER</span><span style="color: black">..spt_values       <br /></span><span style="color: blue">WHERE </span><span style="color: black">number </span><span style="color: gray">&gt; </span><span style="color: black">0       <br />&#160;&#160;&#160; </span><span style="color: gray">AND </span><span style="color: blue">TYPE = </span><span style="color: red">'P'       <br />&#160;&#160;&#160; </span><span style="color: gray">AND </span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">DAY</span><span style="color: gray">,</span><span style="color: black">number</span><span style="color: gray">-</span><span style="color: black">1</span><span style="color: gray">,</span><span style="color: #434343">@dt</span><span style="color: gray">) &gt;= </span><span style="color: #434343">@dt       <br />&#160;&#160;&#160; </span><span style="color: gray">AND </span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">DAY</span><span style="color: gray">,</span><span style="color: black">number</span><span style="color: gray">-</span><span style="color: black">1</span><span style="color: gray">,</span><span style="color: #434343">@dt</span><span style="color: gray">) &lt; </span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">MONTH</span><span style="color: gray">,</span><span style="color: black">1</span><span style="color: gray">,</span><span style="color: #434343">@dt</span><span style="color: gray">)       <br />&#160;&#160;&#160; AND </span><span style="color: magenta">DATENAME</span><span style="color: gray">(</span><span style="color: black">dw</span><span style="color: gray">,</span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">DAY</span><span style="color: gray">,</span><span style="color: black">number</span><span style="color: gray">-</span><span style="color: black">1</span><span style="color: gray">,</span><span style="color: #434343">@dt</span><span style="color: gray">)) LIKE </span><span style="color: #434343">@dow </span><span style="color: gray">+ </span><span style="color: red">'%'</span></code> </p>
<p><code style="font-size: 12px"><span style="color: black">MonthDate&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DayIndex       <br /></span><span style="color: black">----------------------- --------------------       <br /></span><span style="color: black">2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">06 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000 1       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">13 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000 2       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">20 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000 3       <br />2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">27 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000 4 </span></code></p>
<p><code style="font-size: 12px"><span style="color: gray">(</span><span style="color: black">4 row</span><span style="color: gray">(</span><span style="color: black">s</span><span style="color: gray">) </span><span style="color: black">affected</span><span style="color: gray">)</span></code></p>
<p>We now have only the Wednesdays of the month, appropriately indexed.&#160; All we have to do now is filter for the 3rd Wednesday.&#160; Since we cannot use a windowing function in a where clause, we have to wrap this query in a CTE or some structure in order to be able to apply our filter:</p>
<p><code style="font-size: 12px"><span style="color: #434343"><code style="font-size: 12px"><span style="color: black"><code style="font-size: 12px"><span style="color: blue">DECLARE </span><span style="color: #434343">@dt </span><span style="color: blue">DATETIME = </span><span style="color: magenta">GETDATE</span><span style="color: gray">();               <br /></span><span style="color: blue">DECLARE </span><span style="color: #434343">@dow </span><span style="color: blue">VARCHAR</span><span style="color: gray">(</span><span style="color: black">100</span><span style="color: gray">) </span><span style="color: blue">= </span><span style="color: red">'Wednesday'</span><span style="color: gray">;               <br /></span><span style="color: blue">DECLARE </span><span style="color: #434343">@num </span><span style="color: blue">INT = </span><span style="color: black">3</span><span style="color: gray">;                </p>
<p></span><span style="color: green">--This will take off any time portion and set the value to the beginning of the month               <br /></span><span style="color: blue">SET </span><span style="color: #434343">@dt </span><span style="color: blue">= </span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">MONTH</span><span style="color: gray">,</span><span style="color: magenta">DATEDIFF</span><span style="color: gray">(</span><span style="color: magenta">MONTH</span><span style="color: gray">,</span><span style="color: black">0</span><span style="color: gray">,</span><span style="color: #434343">@dt</span><span style="color: gray">),</span><span style="color: black">0</span><span style="color: gray">);                </p>
<p></span><span style="color: blue">WITH </span><span style="color: black">MonthDays </span><span style="color: blue">AS               <br /></span><span style="color: gray">(               <br />&#160;&#160; </span><span style="color: blue">SELECT&#160; </span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">DAY</span><span style="color: gray">,</span><span style="color: black">number</span><span style="color: gray">-</span><span style="color: black">1</span><span style="color: gray">,</span><span style="color: #434343">@dt</span><span style="color: gray">) </span><span style="color: blue">AS </span><span style="color: black">MonthDate</span><span style="color: gray">,               <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: black">ROW_NUMBER</span><span style="color: gray">() </span><span style="color: blue">OVER</span><span style="color: gray">(</span><span style="color: blue">ORDER BY </span><span style="color: black">number</span><span style="color: gray">) </span><span style="color: blue">AS </span><span style="color: black">DayIndex               <br />&#160;&#160; </span><span style="color: blue">FROM MASTER</span><span style="color: black">..spt_values               <br />&#160;&#160; </span><span style="color: blue">WHERE </span><span style="color: black">number </span><span style="color: gray">&gt; </span><span style="color: black">0               <br />&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: gray">AND </span><span style="color: blue">TYPE = </span><span style="color: red">'P'               <br />&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: gray">AND </span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">DAY</span><span style="color: gray">,</span><span style="color: black">number</span><span style="color: gray">-</span><span style="color: black">1</span><span style="color: gray">,</span><span style="color: #434343">@dt</span><span style="color: gray">) &gt;= </span><span style="color: #434343">@dt               <br />&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: gray">AND </span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">DAY</span><span style="color: gray">,</span><span style="color: black">number</span><span style="color: gray">-</span><span style="color: black">1</span><span style="color: gray">,</span><span style="color: #434343">@dt</span><span style="color: gray">) &lt; </span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">MONTH</span><span style="color: gray">,</span><span style="color: black">1</span><span style="color: gray">,</span><span style="color: #434343">@dt</span><span style="color: gray">)               <br />&#160;&#160;&#160;&#160;&#160;&#160; AND </span><span style="color: magenta">DATENAME</span><span style="color: gray">(</span><span style="color: black">dw</span><span style="color: gray">,</span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">DAY</span><span style="color: gray">,</span><span style="color: black">number</span><span style="color: gray">-</span><span style="color: black">1</span><span style="color: gray">,</span><span style="color: #434343">@dt</span><span style="color: gray">)) LIKE </span><span style="color: #434343">@dow </span><span style="color: gray">+ </span><span style="color: red">'%'               <br /></span><span style="color: gray">)               <br /></span><span style="color: blue">SELECT </span><span style="color: black">MonthDate               <br /></span><span style="color: blue">FROM </span><span style="color: black">MonthDays               <br /></span><span style="color: blue">WHERE </span><span style="color: black">DayIndex </span><span style="color: blue">= </span><span style="color: #434343">@num</span></code> </span></code></span></code></p>
<p><code style="font-size: 12px"><span style="color: #434343"><code style="font-size: 12px"><span style="color: black">MonthDate           <br /></span><span style="color: black">-----------------------           <br /></span><span style="color: black">2011</span><span style="color: gray">-</span><span style="color: black">07</span><span style="color: gray">-</span><span style="color: black">20 00</span><span style="color: gray">:</span><span style="color: black">00</span><span style="color: gray">:</span><span style="color: black">00.000 </span></code></span></code></p>
<p><code style="font-size: 12px"><span style="color: #434343"><code style="font-size: 12px"><span style="color: gray">(</span><span style="color: black">1 row</span><span style="color: gray">(</span><span style="color: black">s</span><span style="color: gray">) </span><span style="color: black">affected</span><span style="color: gray">)</span></code> </span></code></p>
<p><code style="font-size: 12px"><span style="color: #434343"><span style="font-family: verdana; color: #111111">So we’re done, right?&#160; Well, there’s still the matter of getting it into one statement – it’s two statements now, not counting the declaration/assignments – you can factor the part that strips off the time and normalizes the root date into the statement, but it looks pretty messy…</span></span></code></p>
<p><code style="font-size: 12px"><span style="color: blue">DECLARE </span><span style="color: #434343">@dt </span><span style="color: blue">DATETIME = </span><span style="color: magenta">GETDATE</span><span style="color: gray">();       <br /></span><span style="color: blue">DECLARE </span><span style="color: #434343">@dow </span><span style="color: blue">VARCHAR</span><span style="color: gray">(</span><span style="color: black">100</span><span style="color: gray">) </span><span style="color: blue">= </span><span style="color: red">'Wednesday'</span><span style="color: gray">;       <br /></span><span style="color: blue">DECLARE </span><span style="color: #434343">@num </span><span style="color: blue">INT = </span><span style="color: black">3</span><span style="color: gray">;        </p>
<p></span><span style="color: blue">WITH </span><span style="color: black">MonthDays </span><span style="color: blue">AS       <br /></span><span style="color: gray">(       <br />&#160;&#160; </span><span style="color: blue">SELECT&#160; </span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">DAY</span><span style="color: gray">,</span><span style="color: black">number</span><span style="color: gray">-</span><span style="color: black">1</span><span style="color: gray">,</span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">MONTH</span><span style="color: gray">,</span><span style="color: magenta">DATEDIFF</span><span style="color: gray">(</span><span style="color: magenta">MONTH</span><span style="color: gray">,</span><span style="color: black">0</span><span style="color: gray">,</span><span style="color: #434343">@dt</span><span style="color: gray">),</span><span style="color: black">0</span><span style="color: gray">)) </span><span style="color: blue">AS </span><span style="color: black">MonthDate</span><span style="color: gray">,       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: black">ROW_NUMBER</span><span style="color: gray">() </span><span style="color: blue">OVER</span><span style="color: gray">(</span><span style="color: blue">ORDER BY </span><span style="color: black">number</span><span style="color: gray">) </span><span style="color: blue">AS </span><span style="color: black">DayIndex       <br />&#160;&#160; </span><span style="color: blue">FROM MASTER</span><span style="color: black">..spt_values       <br />&#160;&#160; </span><span style="color: blue">WHERE </span><span style="color: black">number </span><span style="color: gray">&gt; </span><span style="color: black">0       <br />&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: gray">AND </span><span style="color: blue">TYPE = </span><span style="color: red">'P'       <br />&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: gray">AND </span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">DAY</span><span style="color: gray">,</span><span style="color: black">number</span><span style="color: gray">-</span><span style="color: black">1</span><span style="color: gray">,</span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">MONTH</span><span style="color: gray">,</span><span style="color: magenta">DATEDIFF</span><span style="color: gray">(</span><span style="color: magenta">MONTH</span><span style="color: gray">,</span><span style="color: black">0</span><span style="color: gray">,</span><span style="color: #434343">@dt</span><span style="color: gray">),</span><span style="color: black">0</span><span style="color: gray">)) &gt;= </span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">MONTH</span><span style="color: gray">,</span><span style="color: magenta">DATEDIFF</span><span style="color: gray">(</span><span style="color: magenta">MONTH</span><span style="color: gray">,</span><span style="color: black">0</span><span style="color: gray">,</span><span style="color: #434343">@dt</span><span style="color: gray">),</span><span style="color: black">0</span><span style="color: gray">)       <br />&#160;&#160;&#160;&#160;&#160;&#160; AND </span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">DAY</span><span style="color: gray">,</span><span style="color: black">number</span><span style="color: gray">-</span><span style="color: black">1</span><span style="color: gray">,</span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">MONTH</span><span style="color: gray">,</span><span style="color: magenta">DATEDIFF</span><span style="color: gray">(</span><span style="color: magenta">MONTH</span><span style="color: gray">,</span><span style="color: black">0</span><span style="color: gray">,</span><span style="color: #434343">@dt</span><span style="color: gray">),</span><span style="color: black">0</span><span style="color: gray">)) &lt; </span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">MONTH</span><span style="color: gray">,</span><span style="color: black">1</span><span style="color: gray">,</span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">MONTH</span><span style="color: gray">,</span><span style="color: magenta">DATEDIFF</span><span style="color: gray">(</span><span style="color: magenta">MONTH</span><span style="color: gray">,</span><span style="color: black">0</span><span style="color: gray">,</span><span style="color: #434343">@dt</span><span style="color: gray">),</span><span style="color: black">0</span><span style="color: gray">))       <br />&#160;&#160;&#160;&#160;&#160;&#160; AND </span><span style="color: magenta">DATENAME</span><span style="color: gray">(</span><span style="color: black">dw</span><span style="color: gray">,</span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">DAY</span><span style="color: gray">,</span><span style="color: black">number</span><span style="color: gray">-</span><span style="color: black">1</span><span style="color: gray">,</span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">MONTH</span><span style="color: gray">,</span><span style="color: magenta">DATEDIFF</span><span style="color: gray">(</span><span style="color: magenta">MONTH</span><span style="color: gray">,</span><span style="color: black">0</span><span style="color: gray">,</span><span style="color: #434343">@dt</span><span style="color: gray">),</span><span style="color: black">0</span><span style="color: gray">))) LIKE </span><span style="color: #434343">@dow </span><span style="color: gray">+ </span><span style="color: red">'%'       <br /></span><span style="color: gray">)       <br /></span><span style="color: blue">SELECT </span><span style="color: black">MonthDate       <br /></span><span style="color: blue">FROM </span><span style="color: black">MonthDays       <br /></span><span style="color: blue">WHERE </span><span style="color: black">DayIndex </span><span style="color: blue">= </span><span style="color: #434343">@num       <br /></span></code></p>
<p>And voila! – the answer in one statement.&#160; Here is how I would do it in the form of a function.&#160; I use a second CTE here to clean up some of the mess while still finding the answer in a single statement (there is also an alternate way of filtering for the current month here – normally you shouldn’t apply a function to the “left” side of a search argument, but a) we know that this is a small set and b) we have to apply DATENAME anyway, so we will definitely be scanning):</p>
<p><code style="font-size: 12px"><span style="color: blue">CREATE FUNCTION </span><span style="color: black">nth_weekday_of_month_fn </span><span style="color: gray">(       <br />&#160;&#160; </span><span style="color: #434343">@dt </span><span style="color: blue">DATETIME</span><span style="color: gray">,       <br />&#160;&#160; </span><span style="color: #434343">@dow </span><span style="color: blue">VARCHAR</span><span style="color: gray">(</span><span style="color: black">10</span><span style="color: gray">),       <br />&#160;&#160; </span><span style="color: #434343">@num </span><span style="color: blue">INT       <br /></span><span style="color: gray">)       <br /></span><span style="color: blue">RETURNS DATETIME       <br />AS        <br />BEGIN         </p>
<p>DECLARE </span><span style="color: #434343">@RetDate </span><span style="color: blue">DATETIME</span><span style="color: gray">;        </p>
<p></span><span style="color: blue">WITH </span><span style="color: black">MonthDays </span><span style="color: blue">AS       <br /></span><span style="color: gray">(       <br />&#160;&#160; </span><span style="color: blue">SELECT </span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">DAY</span><span style="color: gray">,</span><span style="color: black">number</span><span style="color: gray">-</span><span style="color: black">1</span><span style="color: gray">,</span><span style="color: magenta">DATEADD</span><span style="color: gray">(</span><span style="color: magenta">MONTH</span><span style="color: gray">,</span><span style="color: magenta">DATEDIFF</span><span style="color: gray">(</span><span style="color: magenta">MONTH</span><span style="color: gray">,</span><span style="color: black">0</span><span style="color: gray">,</span><span style="color: #434343">@dt</span><span style="color: gray">),</span><span style="color: black">0</span><span style="color: gray">)) </span><span style="color: blue">AS </span><span style="color: black">MonthDate       <br />&#160;&#160; </span><span style="color: blue">FROM MASTER</span><span style="color: black">..spt_values       <br />&#160;&#160; </span><span style="color: blue">WHERE </span><span style="color: black">number </span><span style="color: gray">&gt; </span><span style="color: black">0       <br />&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: gray">AND </span><span style="color: blue">TYPE = </span><span style="color: red">'P'       <br /></span><span style="color: gray">)       <br />, </span><span style="color: black">WeekDays </span><span style="color: blue">AS       <br /></span><span style="color: gray">(       <br />&#160;&#160; </span><span style="color: blue">SELECT </span><span style="color: gray">*, </span><span style="color: black">ROW_NUMBER</span><span style="color: gray">() </span><span style="color: blue">OVER</span><span style="color: gray">(</span><span style="color: blue">ORDER BY </span><span style="color: black">MonthDate</span><span style="color: gray">) </span><span style="color: black">DayIndex       <br />&#160;&#160; </span><span style="color: blue">FROM </span><span style="color: black">MonthDays       <br />&#160;&#160; </span><span style="color: blue">WHERE </span><span style="color: magenta">YEAR</span><span style="color: gray">(</span><span style="color: #434343">@dt</span><span style="color: gray">) </span><span style="color: blue">= </span><span style="color: magenta">YEAR</span><span style="color: gray">(</span><span style="color: black">MonthDate</span><span style="color: gray">)       <br />&#160;&#160;&#160;&#160;&#160;&#160; AND </span><span style="color: magenta">MONTH</span><span style="color: gray">(</span><span style="color: #434343">@dt</span><span style="color: gray">) </span><span style="color: blue">= </span><span style="color: magenta">MONTH</span><span style="color: gray">(</span><span style="color: black">MonthDate</span><span style="color: gray">)       <br />&#160;&#160;&#160;&#160;&#160;&#160; AND </span><span style="color: magenta">DATENAME</span><span style="color: gray">(</span><span style="color: black">dw</span><span style="color: gray">,</span><span style="color: black">MonthDate</span><span style="color: gray">) LIKE </span><span style="color: #434343">@dow </span><span style="color: gray">+ </span><span style="color: red">'%'       <br /></span><span style="color: gray">)       <br /></span><span style="color: blue">SELECT </span><span style="color: #434343">@RetDate </span><span style="color: blue">= </span><span style="color: black">MonthDate       <br /></span><span style="color: blue">FROM </span><span style="color: black">WeekDays       <br /></span><span style="color: blue">WHERE </span><span style="color: black">DayIndex </span><span style="color: blue">= </span><span style="color: #434343">@num </span><span style="color: blue">RETURN </span><span style="color: gray">(</span><span style="color: #434343">@RetDate</span><span style="color: gray">) </span><span style="color: blue">END       <br /></span><span style="color: black">GO        </p>
<p></span><span style="color: blue">SELECT </span><span style="color: black">dbo.nth_weekday_of_month_fn</span><span style="color: gray">(</span><span style="color: magenta">GETDATE</span><span style="color: gray">(),</span><span style="color: red">'Wednesday'</span><span style="color: gray">,</span><span style="color: black">3</span><span style="color: gray">)       <br /></span></code></p>
]]></content:encoded>
			<wfw:commentRss>http://mikedefehr.com/2011/07/25/finding-the-nth-weekday-of-a-given-month/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Deadlock Scripts SDEC 2010</title>
		<link>http://mikedefehr.com/2010/10/13/deadlock-scripts-sdec-2010/</link>
		<comments>http://mikedefehr.com/2010/10/13/deadlock-scripts-sdec-2010/#comments</comments>
		<pubDate>Wed, 13 Oct 2010 18:28:43 +0000</pubDate>
		<dc:creator>mdefehr</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://mikedefehr.com/?p=85</guid>
		<description><![CDATA[ [...]]]></description>
			<content:encoded><![CDATA[<p>Here are the Scripts and slides for the presentation on deadlocks at SDEC 2010.  Enjoy!</p>
<p><a href="http://mikedefehr.com/wp-content/uploads/2010/10/DeadlocksSDEC2010.zip">DeadlocksSDEC2010</a></p>
]]></content:encoded>
			<wfw:commentRss>http://mikedefehr.com/2010/10/13/deadlock-scripts-sdec-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Index Review Scripts SDEC 2010</title>
		<link>http://mikedefehr.com/2010/10/12/index-review-scripts-sdec-2010/</link>
		<comments>http://mikedefehr.com/2010/10/12/index-review-scripts-sdec-2010/#comments</comments>
		<pubDate>Wed, 13 Oct 2010 00:31:14 +0000</pubDate>
		<dc:creator>mdefehr</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[Scripts]]></category>

		<guid isPermaLink="false">http://mikedefehr.com/?p=82</guid>
		<description><![CDATA[ [...]]]></description>
			<content:encoded><![CDATA[<p>Welcome to SDEC 2010.  I hope you enjoy(ed) my session on how to do an index review.  Here are the scripts and slides.</p>
<p><a href="http://mikedefehr.com/wp-content/uploads/2010/10/IndexReviewSDEC2010.zip">IndexReviewSDEC2010</a></p>
]]></content:encoded>
			<wfw:commentRss>http://mikedefehr.com/2010/10/12/index-review-scripts-sdec-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to attach a database in Standby</title>
		<link>http://mikedefehr.com/2010/08/31/how-to-attach-a-database-in-standby/</link>
		<comments>http://mikedefehr.com/2010/08/31/how-to-attach-a-database-in-standby/#comments</comments>
		<pubDate>Tue, 31 Aug 2010 19:29:46 +0000</pubDate>
		<dc:creator>mdefehr</dc:creator>
				<category><![CDATA[How To]]></category>
		<category><![CDATA[Scripts]]></category>

		<guid isPermaLink="false">http://mikedefehr.com/2010/08/31/how-to-attach-a-database-in-standby/</guid>
		<description><![CDATA[ [...]]]></description>
			<content:encoded><![CDATA[<p>It’s been awhile since I’ve written, but with summer coming to a close, I’m feeling the itch – and what better to start the season with than a problem that does not seem to have a clear solution:</p>
<p>Let’s say you want to move the physical files in a log shipping secondary that is in Standby mode.&#160; You might think that a quick detach, move the files, reattach and it’s coffee time, right?&#160; Well, no…&#160; You’ll start by doing the detach, which SQL server will let you do, you’ll get everything where you want it, then for the big finish you’ll run attach – and you’ll probably be quite surprised to get:</p>
<p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: &quot;Courier New&quot;; color: red; font-size: 8pt; mso-no-proof: yes">Msg 5120, Level 16, State 101, Line 1
</p>
<p>   </span></p>
<p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: &quot;Courier New&quot;; color: red; font-size: 8pt; mso-no-proof: yes">Unable to open the physical file &quot;&lt;your MDF file&gt;&quot;. Operating system error 5: &quot;5(Access is denied.)&quot;.
</p>
<p>   </span></p>
<p>&#160;</p>
<p>And you might be quite befuddled – and rightly so – you’ll see that the permissions on your files have been reset, so you correct them, but now you get:</p>
<p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: &quot;Courier New&quot;; color: red; font-size: 8pt; mso-no-proof: yes">Msg 1824, Level 16, State 1, Line 1
</p>
<p>   </span></p>
<p class="MsoNormal"><span style="line-height: 115%; font-family: &quot;Courier New&quot;; color: red; font-size: 8pt; mso-no-proof: yes">Cannot attach a database that was being restored.</span><span style="color: red">
</p>
<p>   </span></p>
<p>And there doesn’t really seem to be anything you can do about that – panic might set in as you realize your DR database now appears to be a large, unusable pile of bits and you need to start log shipping all over again from your 3TB backup.</p>
<p>Note that if your database was in NORECOVERY mode (not standby), the UI would not give you the option to detach, but sp_detach_db will work just fine – as will the create for attach, but recovery will run and you will no longer be able to restore logs – you’ll definitely have to start with a full backup if you do this.</p>
<p>All is not lost, however.&#160; The database can be “hacked back in” by creating a placeholder database that is in the same standby state, then switching the files while the DB is offline.&#160; This is not exactly outlined in BOL, and it’s called “hacking in” because this is a hack – this is likely not a supported process, but I’ve seen some very well respected industry experts suggest it on an as-necessary basis – see Paul Randal’s post on it <a href="http://www.sqlskills.com/BLOGS/PAUL/post/Disaster-recovery-101-hack-attach-a-damaged-database.aspx" target="_blank">here</a>.&#160; Note that Paul recommends that the dummy database files be roughly the same size as the database you are hacking in – I’ve seen it work without this, but Paul knows much more than I do… The steps are as follows:</p>
<p>1) You should have at least 3 files: the database file (MDF), the log file (LDF) and the undo/standby file (BAK by default).&#160; Since you’ve already detached them, you’ll have to find them by whatever means you have at your disposal.&#160; If you can’t find them, then perhaps you’re the wrong person to be doing this…&#160; Place them where you want them to be, but rename them.</p>
<p>2) Restore a database (any user database) with standby – the only requirement is that it have the same number and type of files as your main database (again, Paul suggest that they be of similar size as well) – the logical names don’t even have to match – you’ll need to name the database itself what you want your attached database to be named, and place the log, data and undo files wherever you want them to be when you’re done. It doesn’t matter what the contents of this database are as they will be overwritten – if you don’t have any small backups handy, either take a copy-only backup of a small database or create an empty database and take a backup of it</p>
<p>3) Other than the contents of course, this database should now look exactly like you want your attached database to look – it should be in standby mode with all the files in the right place and named the right names</p>
<p>4) Take the database offline – note that this works for standby databases – you don’t have to affect the availability of the rest of your server – but for NORECOVERY databases, you’ll have to bring down the service</p>
<p>5) Rename the files and put your files from step 1 in their place.&#160; Check the file permissions as they may have been reset in the detach</p>
<p>6) Bring the database online</p>
<p>7) Assuming everything works, delete the renamed files from the placeholder database</p>
<p>That should do it.&#160; I’ve tested it a number of ways on SQL 2008, and in a limited fashion on SQL 2005.&#160; I highly recommend doing this with some scratch databases to familiarize yourself with the process before trying it on production.</p>
<p>Note that if all you want to do is get a copy of the database so that you can do something else with it and you don’t actually want to move it, you can simply set it offline, make copies of the files, bring it back online and hack the copies into another location.</p>
<p>Hope this helps.</p>
]]></content:encoded>
			<wfw:commentRss>http://mikedefehr.com/2010/08/31/how-to-attach-a-database-in-standby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Query Tuning and Index Review June 2010</title>
		<link>http://mikedefehr.com/2010/06/23/query-tuning-and-index-review-june-2010/</link>
		<comments>http://mikedefehr.com/2010/06/23/query-tuning-and-index-review-june-2010/#comments</comments>
		<pubDate>Wed, 23 Jun 2010 16:31:17 +0000</pubDate>
		<dc:creator>mdefehr</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[Scripts]]></category>

		<guid isPermaLink="false">http://mikedefehr.com/?p=76</guid>
		<description><![CDATA[ [...]]]></description>
			<content:encoded><![CDATA[<p>Here are the scripts and slides for my session on Query Tuning and Index Reviews.  I hope you enjoy(ed) the session.</p>
<p><a href="http://mikedefehr.com/wp-content/uploads/2010/06/QueryTuningAndIndexReview.zip">QueryTuningAndIndexReview</a></p>
]]></content:encoded>
			<wfw:commentRss>http://mikedefehr.com/2010/06/23/query-tuning-and-index-review-june-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bullet Dodging Scripts Prairie Devcon 2010</title>
		<link>http://mikedefehr.com/2010/06/03/bullet-dodging-scripts-prairie-devcon-2010/</link>
		<comments>http://mikedefehr.com/2010/06/03/bullet-dodging-scripts-prairie-devcon-2010/#comments</comments>
		<pubDate>Thu, 03 Jun 2010 19:27:18 +0000</pubDate>
		<dc:creator>mdefehr</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[Scripts]]></category>

		<guid isPermaLink="false">http://mikedefehr.com/?p=72</guid>
		<description><![CDATA[ [...]]]></description>
			<content:encoded><![CDATA[<p>Here are the scripts for my bullet-dodging and spoon-bending session at Prairie DevCon Regina 2010.  Enjoy!</p>
<p><a href="http://mikedefehr.com/wp-content/uploads/2010/06/BulletSpoon.zip">BulletSpoon</a></p>
]]></content:encoded>
			<wfw:commentRss>http://mikedefehr.com/2010/06/03/bullet-dodging-scripts-prairie-devcon-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Do your T-SQL variables have the right values?</title>
		<link>http://mikedefehr.com/2010/06/02/do-your-t-sql-variables-have-the-right-values/</link>
		<comments>http://mikedefehr.com/2010/06/02/do-your-t-sql-variables-have-the-right-values/#comments</comments>
		<pubDate>Wed, 02 Jun 2010 23:18:17 +0000</pubDate>
		<dc:creator>mdefehr</dc:creator>
				<category><![CDATA[Scripts]]></category>
		<category><![CDATA[You learn something new...]]></category>

		<guid isPermaLink="false">http://mikedefehr.com/2010/06/02/do-your-t-sql-variables-have-the-right-values/</guid>
		<description><![CDATA[ [...]]]></description>
			<content:encoded><![CDATA[<p>For some of us who are bewildered by even the code we write ourselves, this might be a question we ask ourselves in more circumstances than we’d like to admit, but what I’m talking about here is assigning values to a variable with a SELECT statement, and expecting the value to be null if the query didn’t find anything.  This can be particularly nefarious in cursor loops as I will show.  First, to set up the scenario, run the following script.  It creates two temp tables – one with 10 rows and one with 5:</p>
<p><code style="font-size: 12px;"><span style="color: blue;">IF </span><span style="color: magenta;">OBJECT_ID</span><span style="color: gray;">(</span><span style="color: red;">'tempdb..#one'</span><span style="color: gray;">) </span><span style="color: blue;">IS </span><span style="color: gray;">NOT NULL </span><span style="color: blue;">DROP TABLE </span><span style="color: #434343;">#one<br />
</span><span style="color: blue;">IF </span><span style="color: magenta;">OBJECT_ID</span><span style="color: gray;">(</span><span style="color: red;">'tempdb..#two'</span><span style="color: gray;">) </span><span style="color: blue;">IS </span><span style="color: gray;">NOT NULL </span><span style="color: blue;">DROP TABLE </span><span style="color: #434343;">#two<br />
</span><span style="color: blue;">CREATE TABLE </span><span style="color: #434343;">#one </span><span style="color: gray;">(</span><span style="color: black;">number </span><span style="color: blue;">INT </span><span style="color: #434343;">IDENTITY </span><span style="color: gray;">(</span><span style="color: black;">1</span><span style="color: gray;">,</span><span style="color: black;">1</span><span style="color: gray;">))<br />
</span><span style="color: blue;">CREATE TABLE </span><span style="color: #434343;">#two </span><span style="color: gray;">(</span><span style="color: black;">number </span><span style="color: blue;">INT </span><span style="color: #434343;">IDENTITY </span><span style="color: gray;">(</span><span style="color: black;">1</span><span style="color: gray;">,</span><span style="color: black;">1</span><span style="color: gray;">))<br />
</span><span style="color: black;">GO<br />
</span><span style="color: blue;">INSERT </span><span style="color: #434343;">#one </span><span style="color: blue;">DEFAULT VALUES<br />
</span><span style="color: black;">GO 10<br />
</span><span style="color: blue;">INSERT </span><span style="color: #434343;">#two </span><span style="color: blue;">DEFAULT VALUES<br />
</span><span style="color: black;">GO 5<br />
</span><span style="color: blue;">SELECT </span><span style="color: gray;">* </span><span style="color: blue;">FROM </span><span style="color: #434343;">#one<br />
</span><span style="color: blue;">SELECT </span><span style="color: gray;">* </span><span style="color: blue;">FROM </span><span style="color: #434343;">#two</span></code></p>
<p><code style="font-size: 12px;"><span style="color: black;">number<br />
</span><span style="color: black;">-----------<br />
</span><span style="color: black;">1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
8<br />
9<br />
10 </span><span style="color: gray;">(</span><span style="color: black;">10 row</span><span style="color: gray;">(</span><span style="color: black;">s</span><span style="color: gray;">) </span><span style="color: black;">affected</span><span style="color: gray;">) </span><span style="color: black;">number<br />
</span><span style="color: black;">-----------<br />
</span><span style="color: black;">1<br />
2<br />
3<br />
4<br />
5 </span><span style="color: gray;">(</span><span style="color: black;">5 row</span><span style="color: gray;">(</span><span style="color: black;">s</span><span style="color: gray;">) </span><span style="color: black;">affected</span><span style="color: gray;">)</span></code></p>
<p>Now we will use a cursor loop to go through the first (10-record) table and look for matching values in the second table – we should obviously only find 5 matching values – and display our findings.  This is what it *should* look like:</p>
<p><code style="font-size: 12px;"><span style="color: blue;">DECLARE </span><span style="color: #434343;">@CR </span><span style="color: blue;">CURSOR</span><span style="color: gray;">, </span><span style="color: #434343;">@Number </span><span style="color: blue;">INT</span><span style="color: gray;">, </span><span style="color: #434343;">@Found </span><span style="color: blue;">INT<br />
SET </span><span style="color: #434343;">@CR </span><span style="color: blue;">= CURSOR </span><span style="color: black;">LOCAL FAST_FORWARD </span><span style="color: blue;">FOR<br />
SELECT </span><span style="color: black;">number </span><span style="color: blue;">FROM </span><span style="color: #434343;">#one<br />
</span><span style="color: blue;">OPEN </span><span style="color: #434343;">@CR<br />
</span><span style="color: blue;">FETCH </span><span style="color: black;">NEXT </span><span style="color: blue;">FROM </span><span style="color: #434343;">@CR </span><span style="color: blue;">INTO </span><span style="color: #434343;">@Number<br />
</span><span style="color: blue;">WHILE </span><span style="color: #434343;">@@FETCH_STATUS </span><span style="color: blue;">= </span><span style="color: black;">0<br />
</span><span style="color: blue;">BEGIN<br />
   RAISERROR</span><span style="color: gray;">(</span><span style="color: red;">'Looking for number %i...'</span><span style="color: gray;">,</span><span style="color: black;">0</span><span style="color: gray;">,</span><span style="color: black;">0</span><span style="color: gray;">,</span><span style="color: #434343;">@Number</span><span style="color: gray;">)<br />
   </span><span style="color: blue;">SET </span><span style="color: #434343;">@Found </span><span style="color: blue;">=</span><span style="color: gray;">(</span><span style="color: blue;">SELECT </span><span style="color: black;">number </span><span style="color: blue;">FROM </span><span style="color: #434343;">#two </span><span style="color: blue;">WHERE </span><span style="color: black;">number </span><span style="color: blue;">= </span><span style="color: #434343;">@Number</span><span style="color: gray;">)<br />
   </span><span style="color: blue;">IF </span><span style="color: #434343;">@Found </span><span style="color: blue;">IS </span><span style="color: gray;">NOT NULL<br />
       </span><span style="color: blue;">RAISERROR</span><span style="color: gray;">(</span><span style="color: red;">'Found: %i'</span><span style="color: gray;">,</span><span style="color: black;">0</span><span style="color: gray;">,</span><span style="color: black;">0</span><span style="color: gray;">,</span><span style="color: #434343;">@Found</span><span style="color: gray;">)<br />
   </span><span style="color: blue;">FETCH </span><span style="color: black;">NEXT </span><span style="color: blue;">FROM </span><span style="color: #434343;">@CR </span><span style="color: blue;">INTO </span><span style="color: #434343;">@Number<br />
</span><span style="color: blue;">END</span></code></p>
<p><code style="font-size: 12px;"><span style="color: black;">Looking </span><span style="color: black;">for </span><span style="color: black;">number 1...<br />
Found: 1<br />
Looking </span><span style="color: black;">for </span><span style="color: black;">number 2...<br />
Found: 2<br />
Looking </span><span style="color: black;">for </span><span style="color: black;">number 3...<br />
Found: 3<br />
Looking </span><span style="color: black;">for </span><span style="color: black;">number 4...<br />
Found: 4<br />
Looking </span><span style="color: black;">for </span><span style="color: black;">number 5...<br />
Found: 5<br />
Looking </span><span style="color: black;">for </span><span style="color: black;">number 6...<br />
Looking </span><span style="color: black;">for </span><span style="color: black;">number 7...<br />
Looking </span><span style="color: black;">for </span><span style="color: black;">number 8...<br />
Looking </span><span style="color: black;">for </span><span style="color: black;">number 9...<br />
Looking </span><span style="color: black;">for </span><span style="color: black;">number 10...</span></code></p>
<p>Of course, it only found the five (by the way, please don’t take this as a recommendation to use cursors for this type of thing – I’m illustrating an unrelated point here…) How about the following, though – there is a subtle difference – do you see it right away?</p>
<p><code style="font-size: 12px;"><span style="color: blue;">DECLARE </span><span style="color: #434343;">@CR </span><span style="color: blue;">CURSOR</span><span style="color: gray;">, </span><span style="color: #434343;">@Number </span><span style="color: blue;">int</span><span style="color: gray;">, </span><span style="color: #434343;">@Found </span><span style="color: blue;">int<br />
SET </span><span style="color: #434343;">@CR </span><span style="color: blue;">= CURSOR </span><span style="color: black;">LOCAL FAST_FORWARD </span><span style="color: blue;">FOR<br />
SELECT </span><span style="color: black;">number </span><span style="color: blue;">FROM </span><span style="color: #434343;">#one<br />
</span><span style="color: blue;">OPEN </span><span style="color: #434343;">@CR<br />
</span><span style="color: blue;">FETCH </span><span style="color: black;">NEXT </span><span style="color: blue;">FROM </span><span style="color: #434343;">@CR </span><span style="color: blue;">INTO </span><span style="color: #434343;">@Number<br />
</span><span style="color: blue;">WHILE </span><span style="color: #434343;">@@FETCH_STATUS </span><span style="color: blue;">= </span><span style="color: black;">0<br />
</span><span style="color: blue;">BEGIN<br />
   RAISERROR</span><span style="color: gray;">(</span><span style="color: red;">'Looking for number %i...'</span><span style="color: gray;">,</span><span style="color: black;">0</span><span style="color: gray;">,</span><span style="color: black;">0</span><span style="color: gray;">,</span><span style="color: #434343;">@Number</span><span style="color: gray;">)<br />
   </span><span style="color: blue;">SELECT </span><span style="color: #434343;">@Found </span><span style="color: blue;">= </span><span style="color: black;">number </span><span style="color: blue;">FROM </span><span style="color: #434343;">#two </span><span style="color: blue;">WHERE </span><span style="color: black;">number </span><span style="color: blue;">= </span><span style="color: #434343;">@Number<br />
   </span><span style="color: blue;">IF </span><span style="color: #434343;">@Found </span><span style="color: blue;">IS </span><span style="color: gray;">NOT NULL<br />
       </span><span style="color: blue;">RAISERROR</span><span style="color: gray;">(</span><span style="color: red;">'Found: %i'</span><span style="color: gray;">,</span><span style="color: black;">0</span><span style="color: gray;">,</span><span style="color: black;">0</span><span style="color: gray;">,</span><span style="color: #434343;">@Found</span><span style="color: gray;">)<br />
   </span><span style="color: blue;">FETCH </span><span style="color: black;">NEXT </span><span style="color: blue;">FROM </span><span style="color: #434343;">@CR </span><span style="color: blue;">INTO </span><span style="color: #434343;">@Number<br />
</span><span style="color: blue;">END</span></code></p>
<p><code style="font-size: 12px;"><span style="color: black;">Looking </span><span style="color: black;">for </span><span style="color: black;">number 1...<br />
Found: 1<br />
Looking </span><span style="color: black;">for </span><span style="color: black;">number 2...<br />
Found: 2<br />
Looking </span><span style="color: black;">for </span><span style="color: black;">number 3...<br />
Found: 3<br />
Looking </span><span style="color: black;">for </span><span style="color: black;">number 4...<br />
Found: 4<br />
Looking </span><span style="color: black;">for </span><span style="color: black;">number 5...<br />
Found: 5<br />
Looking </span><span style="color: black;">for </span><span style="color: black;">number 6...<br />
Found: 5<br />
Looking </span><span style="color: black;">for </span><span style="color: black;">number 7...<br />
Found: 5<br />
Looking </span><span style="color: black;">for </span><span style="color: black;">number 8...<br />
Found: 5<br />
Looking </span><span style="color: black;">for </span><span style="color: black;">number 9...<br />
Found: 5<br />
Looking </span><span style="color: black;">for </span><span style="color: black;">number 10...<br />
Found: 5 </span></code></p>
<p>So “SELECT @Var =” and “SET @Var =” are the same thing, right? Well, it appears not.  Using the SELECT method, the variable is not resetting to NULL.  There is a simple explanation for this.  The SET method is setting the variable to the output of a query – that query did not return anything which is a missing value – the very definition of NULL – but the SELECT method is changing the variable as part of the query.  Since the query returns no rows, the variable assignment never takes place so the value of the variable does not change.</p>
<p>You may want the variable to change to NULL and you may not – so choose your method accordingly, but I have seen code that uses the SELECT method followed by a test for NULL clearly expecting the variable to be nulled if no record is found.</p>
<p>Exercise:  What happens if you use an aggregate like MAX() with the SELECT method – do you know what it will do before you try it?  Try it and see if you’re right (hint:  aggregate queries always return at least one row).</p>
<p>Be careful out there – the devil is in the details.</p>
<p><code style="font-size: 12px;"><span style="color: black;"><br />
</span></code></p>
]]></content:encoded>
			<wfw:commentRss>http://mikedefehr.com/2010/06/02/do-your-t-sql-variables-have-the-right-values/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Query Tuning Scripts Prairie DevCon 2010</title>
		<link>http://mikedefehr.com/2010/06/02/query-tuning-scripts-prairie-devcon-2010/</link>
		<comments>http://mikedefehr.com/2010/06/02/query-tuning-scripts-prairie-devcon-2010/#comments</comments>
		<pubDate>Wed, 02 Jun 2010 22:18:44 +0000</pubDate>
		<dc:creator>mdefehr</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[Scripts]]></category>

		<guid isPermaLink="false">http://mikedefehr.com/?p=63</guid>
		<description><![CDATA[ [...]]]></description>
			<content:encoded><![CDATA[<p>Here are the scripts from the session.  I hope you enjoyed it.  Sorry that I got a bit carried away and didn&#8217;t quite finish.  At the end of the demo script you&#8217;ll see that we were going to actually optimize a query&#8230;  But the tools, and what to look for are the most important piece anyway.  Feel free to post a comment or send me mail if you have any questions.  Enjoy the rest of the conference.</p>
<p><a href="http://mikedefehr.com/wp-content/uploads/2010/06/IntroQueryTuning.zip">IntroQueryTuning</a></p>
]]></content:encoded>
			<wfw:commentRss>http://mikedefehr.com/2010/06/02/query-tuning-scripts-prairie-devcon-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Transfer files with RDP</title>
		<link>http://mikedefehr.com/2010/05/13/transfer-files-with-rdp/</link>
		<comments>http://mikedefehr.com/2010/05/13/transfer-files-with-rdp/#comments</comments>
		<pubDate>Thu, 13 May 2010 21:17:31 +0000</pubDate>
		<dc:creator>mdefehr</dc:creator>
				<category><![CDATA[You learn something new...]]></category>

		<guid isPermaLink="false">http://mikedefehr.com/2010/05/13/transfer-files-with-rdp/</guid>
		<description><![CDATA[ [...]]]></description>
			<content:encoded><![CDATA[<p>In the spirit of “you learn something new every day” I’ve been using Remote Desktop for years.  I use it almost every day.  Sometimes I’m remoted into machines that are remoted into other machines and so on (it can be very confusing).  But I did not know that you can map a drive on the machine you’re remoting into back to the machine you are remoting from.</p>
<p>In a lot of scenarios you are remoting into machines on the same network so transferring files is not an issue.  Sometimes, though, you’re remoting into a machine on the other end of the internet – it may not be running an FTP service or it may just be a pain to upload files to somewhere that this machine can download them from securely or conveniently. </p>
<p>If, before you establish the RDP connection, you go into options and look at the local resources tab (and depending on your version of RDP, click the “more” button) you’ll see you can check off “drives”.  Once in the session, you’ll see the local drives under “My Computer”.  It’s not the fastest interface, but it is pretty slick.</p>
]]></content:encoded>
			<wfw:commentRss>http://mikedefehr.com/2010/05/13/transfer-files-with-rdp/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SQL MVP Nominee</title>
		<link>http://mikedefehr.com/2010/05/13/sql-mvp-nominee/</link>
		<comments>http://mikedefehr.com/2010/05/13/sql-mvp-nominee/#comments</comments>
		<pubDate>Thu, 13 May 2010 17:21:58 +0000</pubDate>
		<dc:creator>mdefehr</dc:creator>
				<category><![CDATA[About me]]></category>

		<guid isPermaLink="false">http://mikedefehr.com/2010/05/13/sql-mvp-nominee/</guid>
		<description><![CDATA[ [...]]]></description>
			<content:encoded><![CDATA[<p>I am proud to say that I have been nominated for the MVP award.&#160; It is gratifying to know that somebody out there thinks that what I do is helpful.&#160; I will find out in July if I made it.</p>
]]></content:encoded>
			<wfw:commentRss>http://mikedefehr.com/2010/05/13/sql-mvp-nominee/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

