<?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>Strate SQL &#187; SQL Server 2000</title>
	<atom:link href="http://www.jasonstrate.com/index.php/category/sqlserver/sqlserver2000/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jasonstrate.com</link>
	<description>Questions, answers, opinions and scripts from a SQL Server DBA</description>
	<lastBuildDate>Tue, 31 Aug 2010 02:56:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Grouping and Rounding Dates</title>
		<link>http://www.jasonstrate.com/index.php/2010/03/grouping-and-rounding-dates/</link>
		<comments>http://www.jasonstrate.com/index.php/2010/03/grouping-and-rounding-dates/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 14:00:00 +0000</pubDate>
		<dc:creator>jstrate</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server 2000]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2008]]></category>
		<category><![CDATA[SQLServerSyndication]]></category>
		<category><![CDATA[T-SQL]]></category>
		<category><![CDATA[Tip]]></category>

		<guid isPermaLink="false">http://www.jasonstrate.com/index.php/2010/03/grouping-and-rounding-dates/</guid>
		<description><![CDATA[Ever need to group dates and round them to intervals?  I had this exact need for a report on wait stats I was working on for an upcoming post.  I wanted the flexibility to be able to group a list of dates by either minute, hour, date, etc.  And then also round those dates within [...]


Related posts:<ol><li><a href='http://www.jasonstrate.com/index.php/2009/02/rounding-up-to-the-nearest-1000/' rel='bookmark' title='Permanent Link: Rounding Up to the Nearest 1,000'>Rounding Up to the Nearest 1,000</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2009/10/checking-exists-whats-your-practice/' rel='bookmark' title='Permanent Link: Checking EXISTS &ndash; What&rsquo;s Your Practice?'>Checking EXISTS &ndash; What&rsquo;s Your Practice?</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2010/02/please-no-trim/' rel='bookmark' title='Permanent Link: Please, no TRIM()?'>Please, no TRIM()?</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.jasonstrate.com%2Findex.php%2F2010%2F03%2Fgrouping-and-rounding-dates%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.jasonstrate.com%2Findex.php%2F2010%2F03%2Fgrouping-and-rounding-dates%2F" height="61" width="51" /></a></div><p><a title="DSC01618" href="http://www.flickr.com/photos/30208086@N00/2277563006/"><img style="margin: 0px 10px 10px 0px; display: inline;" src="http://static.flickr.com/2313/2277563006_52154379bb.jpg" border="0" alt="DSC01618" width="141" height="183" align="left" /></a>Ever need to group dates and round them to intervals?  I had this exact need for a report on wait stats I was working on for an upcoming post.  I wanted the flexibility to be able to group a list of dates by either minute, hour, date, etc.  And then also round those dates within those intervals.  For example, round a list of dates to every 15 minutes, every 3 hours, or every 2 days.  At first thought this sounded like something that might be a little tricky to accomplish.  But as I’ll show in the examples below, this is quite easy.</p>
<h4>Start With The First of the Month</h4>
<p>To resolve this issue, I started by using the logic that I typically when I need to take a date and change it to the first day of a month or quarter.  The logic I use for that utilizes the <a href="http://msdn.microsoft.com/en-us/library/ms186819.aspx" target="_blank">DATEADD</a> and <a href="http://msdn.microsoft.com/en-us/library/ms189794.aspx" target="_blank">DATEDIFF</a> functions.  I’ll skip going into how those work since Books Online covers that pretty well. </p>
<p>To find the start of a month or quarter, these functions can be used together to be compare a date and time against the value 0.  Casting 0 as datetime returns the value <strong>1900-01-01 00:00:00.000</strong>.  Using the two functions together, use DATEDIFF to determine how many months or quarters have occurred since 1900-01-01.  And then use DATEADD to add those months or quarters to the date 1900-01-01.  Doing this will provide you with the the first day in either the month or the quarter.</p>
<p>The examples below can be used to demonstrate this:</p>
<pre class="brush: sql; ">

SELECT DATEADD(M, DATEDIFF(M, 0, &#039;20100310&#039;), 0)
GO

SELECT DATEADD(Q, DATEDIFF(Q, 0, &#039;20100310&#039;), 0)
GO
</pre>
<p>Returning the following results:</p>
<p><a href="http://www.jasonstrate.com/images/GroupandRoundingDates_B81D/DateAddDateDiff.jpg"><img style="display: inline; border-width: 0px;" title="DateAddDateDiff" src="http://www.jasonstrate.com/images/GroupandRoundingDates_B81D/DateAddDateDiff_thumb.jpg" border="0" alt="DateAddDateDiff" width="194" height="144" /></a></p>
<h4>Round to the Desired Interval</h4>
<p>Now that’s the easy part which leaves the next part, where dates and times need to be rounded not to the 1st of the month put to periods that are determined at execution time.  As I mentioned above, I need to change the logic above such that I can get dates to round to every 1 week or 2 days or 3 hours.</p>
<p>On the surface, this sounded a lot harder than it turned out to be.  Because if you use the <a href="http://msdn.microsoft.com/en-us/library/ms190279.aspx" target="_blank">%</a> to find the remainder of division, you can easy round any date or time to any logical grouping of dates or times. </p>
<p>Suppose you need to round a datetime to the nearest 4 hours.  Find the distance in hours between 1900-01-01 and the datetime in question.  Take that number and find the modulo using your rounding interval.  In this case that value is 4.  Then subtract the remainder from the distance.  And use the new distance value in the DATEADD function from 1900-01-01.  <strike>Hopefully, that didn’t lose too many people.</strike></p>
<p>Rather than explain it another way, take a look at the following T-SQL statements where the datetime is rounded down to the nearest 2, 3, and 4 hour intervals.</p>
<pre class="brush: sql; ">

--Round down to nearest 2 hours.
SELECT DATEADD(HH, DATEDIFF(HH, 0, &#039;2010-03-10 03:00:00.000&#039;)-(DATEDIFF(HH, 0, &#039;2010-03-10 03:00:00.000&#039;)%2), 0)
GO

--Round down to nearest 3 hours.
SELECT DATEADD(HH, DATEDIFF(HH, 0, &#039;2010-03-10 03:00:00.000&#039;)-(DATEDIFF(HH, 0, &#039;2010-03-10 03:00:00.000&#039;)%3), 0)
GO

--Round down to nearest 4 hours.
SELECT DATEADD(HH, DATEDIFF(HH, 0, &#039;2010-03-10 03:00:00.000&#039;)-(DATEDIFF(HH, 0, &#039;2010-03-10 03:00:00.000&#039;)%4), 0)
GO
</pre>
<p>These statements produce the following results:</p>
<p><a href="http://www.jasonstrate.com/images/GroupandRoundingDates_B81D/DateAddDateDiff2.jpg"><img style="display: inline; border-width: 0px;" title="DateAddDateDiff2" src="http://www.jasonstrate.com/images/GroupandRoundingDates_B81D/DateAddDateDiff2_thumb.jpg" border="0" alt="DateAddDateDiff2" width="197" height="201" /></a> </p>
<p>As you’ll hopefully see, this is a very simple technique.  Imagine replacing the hour, day, or month date parts with a variable and then the interval to round the dates with a variable.  Doing that and the expression can be used in a stored procedure or report to group any set of dates along any set of date or time groupings.</p>
<p>Hope you find this as useful as I did.  And in the next couple days, I hope to have something up that uses this technique to make it even easier to use in your own code by providing fully working examples.</p>


<p>Related posts:<ol><li><a href='http://www.jasonstrate.com/index.php/2009/02/rounding-up-to-the-nearest-1000/' rel='bookmark' title='Permanent Link: Rounding Up to the Nearest 1,000'>Rounding Up to the Nearest 1,000</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2009/10/checking-exists-whats-your-practice/' rel='bookmark' title='Permanent Link: Checking EXISTS &ndash; What&rsquo;s Your Practice?'>Checking EXISTS &ndash; What&rsquo;s Your Practice?</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2010/02/please-no-trim/' rel='bookmark' title='Permanent Link: Please, no TRIM()?'>Please, no TRIM()?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.jasonstrate.com/index.php/2010/03/grouping-and-rounding-dates/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Please, no TRIM()?</title>
		<link>http://www.jasonstrate.com/index.php/2010/02/please-no-trim/</link>
		<comments>http://www.jasonstrate.com/index.php/2010/02/please-no-trim/#comments</comments>
		<pubDate>Fri, 12 Feb 2010 14:30:00 +0000</pubDate>
		<dc:creator>jstrate</dc:creator>
				<category><![CDATA[Performance Tuning]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server 2000]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2008]]></category>
		<category><![CDATA[SQLServerSyndication]]></category>
		<category><![CDATA[T-SQL]]></category>
		<category><![CDATA[Tip]]></category>

		<guid isPermaLink="false">http://www.jasonstrate.com/index.php/2010/02/please-no-trim/</guid>
		<description><![CDATA[A couple weeks back I was asked, “How come Microsoft has yet to put TRIM() in SQL?”
I don’t really know why there isn’t a TRIM() function in SQL Server. There is an LTRIM for function removing leading spaces. And an RTRIM function for removing trailing spaces. But there isn’t a TRIM function.
Let’s be honest, the [...]


Related posts:<ol><li><a href='http://www.jasonstrate.com/index.php/2009/02/rounding-up-to-the-nearest-1000/' rel='bookmark' title='Permanent Link: Rounding Up to the Nearest 1,000'>Rounding Up to the Nearest 1,000</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2009/01/scripting-object-level-permissions/' rel='bookmark' title='Permanent Link: Scripting Object Level Permissions'>Scripting Object Level Permissions</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2010/03/grouping-and-rounding-dates/' rel='bookmark' title='Permanent Link: Grouping and Rounding Dates'>Grouping and Rounding Dates</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.jasonstrate.com%2Findex.php%2F2010%2F02%2Fplease-no-trim%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.jasonstrate.com%2Findex.php%2F2010%2F02%2Fplease-no-trim%2F" height="61" width="51" /></a></div><p><a title="Nose Trim" href="http://www.flickr.com/photos/83015312@N00/1367791068/"><img style="margin: 0px 10px 10px 0px; display: inline;" src="http://static.flickr.com/1242/1367791068_6e52d2341d.jpg" border="0" alt="Nose Trim" width="119" height="164" align="left" /></a>A couple weeks back I was asked, “How come Microsoft has yet to put TRIM() in SQL?”</p>
<p>I don’t really know why there isn’t a TRIM() function in SQL Server. There is an LTRIM for function removing leading spaces. And an RTRIM function for removing trailing spaces. But there isn’t a TRIM function.</p>
<p>Let’s be honest, the why doesn’t matter to me – I don’t want the function to be a part of SQL Server. So Instead of figuring out why, I’m going to write about my opinions. This is a great place for them, this being my blog and all.</p>
<p>There are two main reasons that I am against having a TRIM function in SQL Server…</p>
<h3>What Do You Know</h3>
<p>First, a large majority of people tend to stick with what they know. Once you find something that works, why not stick with it until there is a reason not to use it any longer. Unfortunately this can have some unintended consequences.</p>
<p><a title="Interactive Playpen" href="http://www.flickr.com/photos/85429509@N00/2317607302/"><img style="margin: 0px 0px 10px 10px; display: inline;" src="http://static.flickr.com/2157/2317607302_668956ffff.jpg" border="0" alt="Interactive Playpen" width="200" height="165" align="right" /></a>Most of the developers that have built the applications that I consult on were originally designed by application developers versus SQL Server developers. This distinction is important because a lot of these developers are then aware of the .NET or Java function for TRIM in the languages that they are using. In their cases, using it will not have a seriously negative impact on their environments.</p>
<p>But that “knowledge of a function” doesn’t translate well into SQL Server. In SQL Server, the use of TRIM would have a serious impact on the effectiveness of indexing being used to query the database. In case you don’t believe me, this will be demonstrated below.</p>
<h3>What Do You Need</h3>
<p>Secondly, how often do leading spaces need to be removed from a field? Sure, I’ve removed them while loading data into a database in an ETL process. But most often, leading space saved to a field in a database is just “bad” data that I’d rather clean up.</p>
<p>Are there reasons to have leading spaces in a field? Probably, but a vast majority of the time they won’t be there and they aren’t going to be needed.</p>
<p>By this logic, most of the time only trailing spaces will need to be removed from a field.</p>
<h3>Considering the Two Reasons</h3>
<p>If leading spaces don’t need to removed but people know about TRIM from their primary programming language, will they be inclined to find out if there is a function the only removes trailing spaces? Or would a person be more inclined to just use what they know. I understand the nature of laziness and pretty confident that people would end up just using TRIM().</p>
<p>Depending on the spaces that need to be removed can have a serious impact on performance. As an example of the performance impact let’s consider the following query.</p>
<div id="codeSnippetWrapper" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;">
<pre id="codeSnippet" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #0000ff;">USE</span> AdventureWorks

<span style="color: #0000ff;">SELECT</span> * <span style="color: #0000ff;">FROM</span> Person.Contact<span style="color: #0000ff;">
WHERE</span> EmailAddress = <span style="color: #006080;">'gustavo0@adventure-works.com'</span></pre>
</div>
<p>When executed, the query returns the following execution plan:</p>
<p><a href="http://www.jasonstrate.com/images/PleasenoTRIM_BBD0/Trim001.jpg"><img style="display: inline; border: 0px;" title="Trim001" src="http://www.jasonstrate.com/images/PleasenoTRIM_BBD0/Trim001_thumb.jpg" border="0" alt="Trim001" width="373" height="204" /></a></p>
<p>You’ll notice that since there is an index on the column EmailAddress, that the Query Optimizer chooses an Index Seek on the column to find the value(s) the are being filtered. And then it looks up the rest of the columns with a Key Lookup operation.</p>
<p>Suppose though that the column had trailing spaces in it that needed to be removed when querying the data. To do this, you’d need to use the RTRIM() function. The query in this case would likely look like this.</p>
<div id="codeSnippetWrapper" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;">
<pre id="codeSnippet" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #0000ff;">USE</span> AdventureWorks

<span style="color: #0000ff;">SELECT</span> * <span style="color: #0000ff;">FROM</span> Person.Contact<span style="color: #0000ff;">
WHERE</span> RTRIM(EmailAddress) = <span style="color: #006080;"><a href="mailto:'gustavo0@adventure-works.com'">'gustavo0@adventure-works.com'</a></span></pre>
</div>
<p>And when executed the query would return the following execution plan:</p>
<p><a href="http://www.jasonstrate.com/images/PleasenoTRIM_BBD0/Trim002.jpg"><img style="display: inline; border: 0px;" title="Trim002" src="http://www.jasonstrate.com/images/PleasenoTRIM_BBD0/Trim002_thumb.jpg" border="0" alt="Trim002" width="386" height="204" /></a></p>
<p>And in this case, the Query Optimizer has chosen to use an Index Scan. It can do this because SQL Server knows how the value begins and can scan for similar values within the index. And then follow-up with a Key Lookup for the rest of the values in the query.</p>
<p>But what we really are talking about is a function that removes the leading and the trailing spaces. To do this you would need to use the LTRIM() function in conjunction with the RTRIM() function. And now the query would look something like this:</p>
<div id="codeSnippetWrapper" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;">
<pre id="codeSnippet" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #0000ff;">USE</span> AdventureWorks

<span style="color: #0000ff;">SELECT</span> * <span style="color: #0000ff;">FROM</span> Person.Contact<span style="color: #0000ff;">
WHERE</span> LTRIM(RTRIM(EmailAddress)) = <span style="color: #006080;">'gustavo0@adventure-works.com'</span></pre>
</div>
<p>Running that query would produce the following execution plan:</p>
<p><a href="http://www.jasonstrate.com/images/PleasenoTRIM_BBD0/Trim003.jpg"><img style="display: inline; border: 0px;" title="Trim003" src="http://www.jasonstrate.com/images/PleasenoTRIM_BBD0/Trim003_thumb.jpg" border="0" alt="Trim003" width="395" height="218" /></a></p>
<p>As you see now, the execution plan is quite different from the previous two executions. Now, the Query Optimizer doesn’t know the first letters of the values in the EmailAddress column. With the existing index being useless, the query doesn’t have any other good candidate to find the values from the WHERE clause. This results in the query just doing a Clustered Index Scan.</p>
<p>Of course, the last execution plan looks like it is simpler, but closer scrutiny of the execution would show that the IO between each of the queries has some significant differences.</p>
<div id="codeSnippetWrapper" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;">
<pre id="codeSnippet" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;">--EmailAddress = <span style="color: #006080;">'gustavo0@adventure-works.com'</span><span style="color: #0000ff;">Table</span> <span style="color: #006080;">'Contact'</span>. Scan <span style="color: #0000ff;">count</span> 1, logical <span style="color: #0000ff;">reads</span> 5, physical <span style="color: #0000ff;">reads</span> 0, <span style="color: #0000ff;">read</span>-ahead <span style="color: #0000ff;">reads</span> 0, lob logical <span style="color: #0000ff;">reads</span> 0, lob physical <span style="color: #0000ff;">reads</span> 0, lob <span style="color: #0000ff;">read</span>-ahead <span style="color: #0000ff;">reads</span> 0.

--RTRIM(EmailAddress) = <span style="color: #006080;">'gustavo0@adventure-works.com'</span>
<span style="color: #0000ff;">Table</span> <span style="color: #006080;">'Contact'</span>. Scan <span style="color: #0000ff;">count</span> 1, logical <span style="color: #0000ff;">reads</span> 178, physical <span style="color: #0000ff;">reads</span> 0, <span style="color: #0000ff;">read</span>-ahead <span style="color: #0000ff;">reads</span> 0, lob logical <span style="color: #0000ff;">reads</span> 0, lob physical <span style="color: #0000ff;">reads</span> 0, lob <span style="color: #0000ff;">read</span>-ahead <span style="color: #0000ff;">reads</span> 0.

--LTRIM(RTRIM(EmailAddress)) = <span style="color: #006080;">'gustavo0@adventure-works.com'</span>
<span style="color: #0000ff;">Table</span> <span style="color: #006080;">'Contact'</span>. Scan <span style="color: #0000ff;">count</span> 1, logical <span style="color: #0000ff;">reads</span> 569, physical <span style="color: #0000ff;">reads</span> 0, <span style="color: #0000ff;">read</span>-ahead <span style="color: #0000ff;">reads</span> 0, lob logical <span style="color: #0000ff;">reads</span> 0, lob physical <span style="color: #0000ff;">reads</span> 0, lob <span style="color: #0000ff;">read</span>-ahead <span style="color: #0000ff;">reads</span> 0.</pre>
</div>
<p>Based on my people going with what they know, the addition of a TRIM() function would likely result in some serious performance issues with some queries. This would likely happen just as a matter of development without any thought as to the effect and difference between the performance of RTRIM(), LTRIM(), and TRIM().</p>
<h3>Some People Want TRIM</h3>
<p>Now my opinion isn’t the only one that is out there. Quite often developers I work with ask about the TRIM() function. And Pinal Dave (blogging at <a href="http://blog.sqlauthority.com/2009/06/03/sql-server-connect-item-vote-for-feature-request-function-trim/" target="_blank">SQLAuthority</a>) put in a <a href="https://connect.microsoft.com/onecare/feedback/details/459062/sql-server-feature-request-trim" target="_blank">Connect item regarding adding a TRIM() function</a>. He’s had a number of posts regarding this topic and ways to get around the lack of a TRIM() function.</p>
<p>While I appreciate the discussions I’ve had with him, one of those time on the <a href="http://blog.sqlauthority.com/2009/11/16/sqlauthority-news-notes-of-excellent-experience-at-sql-pass-2009-summit-seattle/" target="_blank">cursed “it depends”</a>, I’ll have to disagree with him on adding a TRIM() function. The pain in this discovery from people just coming to SQL Server is worth the benefit of unnecessary performance death that could occur by overuse of a TRIM() function. I actually would encourage people to vote down this Connect item.</p>


<p>Related posts:<ol><li><a href='http://www.jasonstrate.com/index.php/2009/02/rounding-up-to-the-nearest-1000/' rel='bookmark' title='Permanent Link: Rounding Up to the Nearest 1,000'>Rounding Up to the Nearest 1,000</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2009/01/scripting-object-level-permissions/' rel='bookmark' title='Permanent Link: Scripting Object Level Permissions'>Scripting Object Level Permissions</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2010/03/grouping-and-rounding-dates/' rel='bookmark' title='Permanent Link: Grouping and Rounding Dates'>Grouping and Rounding Dates</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.jasonstrate.com/index.php/2010/02/please-no-trim/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Checking EXISTS &#8211; What&#8217;s Your Practice?</title>
		<link>http://www.jasonstrate.com/index.php/2009/10/checking-exists-whats-your-practice/</link>
		<comments>http://www.jasonstrate.com/index.php/2009/10/checking-exists-whats-your-practice/#comments</comments>
		<pubDate>Tue, 06 Oct 2009 12:00:00 +0000</pubDate>
		<dc:creator>jstrate</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server 2000]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2008]]></category>
		<category><![CDATA[T-SQL]]></category>
		<category><![CDATA[Tip]]></category>

		<guid isPermaLink="false">http://www.jasonstrate.com/?p=278</guid>
		<description><![CDATA[     Michael Swart (Database Whisperer) posted a great write up and interview with Brad Schulz that is worth checking out.&#160; Michael’s post links to a post from Brad on the use of EXIST and what is required for the SELECT portion of the statement.&#160; Hope you are still with me.
Definitely worth [...]


Related posts:<ol><li><a href='http://www.jasonstrate.com/index.php/2010/03/grouping-and-rounding-dates/' rel='bookmark' title='Permanent Link: Grouping and Rounding Dates'>Grouping and Rounding Dates</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2009/02/rounding-up-to-the-nearest-1000/' rel='bookmark' title='Permanent Link: Rounding Up to the Nearest 1,000'>Rounding Up to the Nearest 1,000</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2010/02/please-no-trim/' rel='bookmark' title='Permanent Link: Please, no TRIM()?'>Please, no TRIM()?</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.jasonstrate.com%2Findex.php%2F2009%2F10%2Fchecking-exists-whats-your-practice%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.jasonstrate.com%2Findex.php%2F2009%2F10%2Fchecking-exists-whats-your-practice%2F" height="61" width="51" /></a></div><p><a href="http://stratesql.com/images/0/0/5/8/4/157902-148500/Old%20microphone_2.jpg">     <br /><img title="Old microphone" border="0" alt="Old microphone" align="right" src="http://stratesql.com/images/0/0/5/8/4/157902-148500/Old%20microphone_thumb.jpg" width="126" height="179" /></a>Michael Swart (<a href="http://dbwhisperer.blogspot.com/">Database Whisperer</a>) posted a <a href="http://dbwhisperer.blogspot.com/2009/10/spotlight-on-brad-schulz-yall.html">great write up and interview</a> with <a href="http://bradsruminations.blogspot.com/">Brad Schulz</a> that is worth checking out.&#160; Michael’s post links to a post from Brad on the <a href="http://bradsruminations.blogspot.com/2009/09/age-old-select-vs-select-1-debate.html">use of EXIST and what is required for the SELECT portion of the statement</a>.&#160; <strike>Hope you are still with me.</strike></p>
<p>Definitely worth the read and +1&#160; for my blog subscriber list.</p>
<p>As he demonstrates, it doesn’t matter whether you use SELECT *, SELECT 1 or SELECT 1/0.&#160; If you want to know what this means, please read his post. </p>
<p>From SQL Server’s perspective, it doesn’t consider any of this information in preparing the results.&#160; The only thing that matters and this is from a practices perspective is to select a style for writing EXISTS statements and sticking to it.</p>


<p>Related posts:<ol><li><a href='http://www.jasonstrate.com/index.php/2010/03/grouping-and-rounding-dates/' rel='bookmark' title='Permanent Link: Grouping and Rounding Dates'>Grouping and Rounding Dates</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2009/02/rounding-up-to-the-nearest-1000/' rel='bookmark' title='Permanent Link: Rounding Up to the Nearest 1,000'>Rounding Up to the Nearest 1,000</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2010/02/please-no-trim/' rel='bookmark' title='Permanent Link: Please, no TRIM()?'>Please, no TRIM()?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.jasonstrate.com/index.php/2009/10/checking-exists-whats-your-practice/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rounding Up to the Nearest 1,000</title>
		<link>http://www.jasonstrate.com/index.php/2009/02/rounding-up-to-the-nearest-1000/</link>
		<comments>http://www.jasonstrate.com/index.php/2009/02/rounding-up-to-the-nearest-1000/#comments</comments>
		<pubDate>Tue, 17 Feb 2009 17:34:00 +0000</pubDate>
		<dc:creator>jstrate</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server 2000]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2008]]></category>
		<category><![CDATA[T-SQL]]></category>
		<category><![CDATA[Tip]]></category>

		<guid isPermaLink="false">http://www.jasonstrate.com/?p=165</guid>
		<description><![CDATA[A co-worker came over and asked how to round up to the nearest 1,000.  He tried to use ROUND but found that it always split between going up or going down depending on the value and the report he was working on always had to round up.
Almost before he finished asking, actually before he finished [...]


Related posts:<ol><li><a href='http://www.jasonstrate.com/index.php/2010/03/grouping-and-rounding-dates/' rel='bookmark' title='Permanent Link: Grouping and Rounding Dates'>Grouping and Rounding Dates</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2010/02/please-no-trim/' rel='bookmark' title='Permanent Link: Please, no TRIM()?'>Please, no TRIM()?</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2009/10/checking-exists-whats-your-practice/' rel='bookmark' title='Permanent Link: Checking EXISTS &ndash; What&rsquo;s Your Practice?'>Checking EXISTS &ndash; What&rsquo;s Your Practice?</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.jasonstrate.com%2Findex.php%2F2009%2F02%2Frounding-up-to-the-nearest-1000%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.jasonstrate.com%2Findex.php%2F2009%2F02%2Frounding-up-to-the-nearest-1000%2F" height="61" width="51" /></a></div><p>A co-worker came over and asked how to round up to the nearest 1,000.  He tried to use <a href="http://msdn.microsoft.com/en-us/library/ms175003.aspx">ROUND</a> but found that it always split between going up or going down depending on the value and the report he was working on always had to round up.</p>
<p>Almost before he finished asking, actually before he finished asking, I said, “<a href="http://msdn.microsoft.com/en-us/library/ms189818.aspx">CEILING</a>”.  Books Online defines the CEILING function as the following:</p>
<blockquote><p><em>Returns the smallest integer greater than, or equal to, the specified numeric expression.</em></p></blockquote>
<p>A quick example from Books Online:</p>
<pre class="brush: sql; ">

SELECT CEILING($123.45), CEILING($-123.45), CEILING($0.0)
GO
</pre>
<p>The example provides the following output:</p>
<p><a href="http://stratesql.com/images/0/0/5/8/4/157902-148500/image_4.png"><img title="image" src="http://stratesql.com/images/0/0/5/8/4/157902-148500/image_thumb_1.png" border="0" alt="image" width="377" height="51" /></a></p>
<p>It’s a fairly simple function, but there isn’t an option to break this out to the tens, hundreds, or thousands.  To do this, I suggested he modify the base value that he needed by 1,000 to get the CEILING value and then multiply it back by the base value of 1,000.</p>
<p>The following is the example code that I showed him:</p>
<pre class="brush: sql; ">

DECLARE @Value decimal(12,3)
SET @Value = 9321.12
SELECT @Value as Original
,CEILING(@Value/1000)*1000 as Ceiling_Pos
,CEILING(-@Value/1000)*1000 as Ceiling_Neg
,ROUND(@Value, -3) as Round_Pos
,ROUND(-@Value, -3) as Round_Neg
</pre>
<p>In the second column, the CEILING function produced the result he was looking for:</p>
<p><a href="http://stratesql.com/images/0/0/5/8/4/157902-148500/image_12.png"><img title="image" src="http://stratesql.com/images/0/0/5/8/4/157902-148500/image_thumb_5.png" border="0" alt="image" width="399" height="53" /></a></p>
<p>I included the use of the ROUND function to show that it did not produce the required result.  This method also works if you need to round up to the nearest 250, 50, 5, or 333rd.  Ok… it only mostly works with the 333rd and has a rounding issue, but that would just be a goofy requirement so I can live with that.</p>
<p>Hopefully, this can help others with their rounding up needs.</p>


<p>Related posts:<ol><li><a href='http://www.jasonstrate.com/index.php/2010/03/grouping-and-rounding-dates/' rel='bookmark' title='Permanent Link: Grouping and Rounding Dates'>Grouping and Rounding Dates</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2010/02/please-no-trim/' rel='bookmark' title='Permanent Link: Please, no TRIM()?'>Please, no TRIM()?</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2009/10/checking-exists-whats-your-practice/' rel='bookmark' title='Permanent Link: Checking EXISTS &ndash; What&rsquo;s Your Practice?'>Checking EXISTS &ndash; What&rsquo;s Your Practice?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.jasonstrate.com/index.php/2009/02/rounding-up-to-the-nearest-1000/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scripting Object Level Permissions</title>
		<link>http://www.jasonstrate.com/index.php/2009/01/scripting-object-level-permissions/</link>
		<comments>http://www.jasonstrate.com/index.php/2009/01/scripting-object-level-permissions/#comments</comments>
		<pubDate>Fri, 09 Jan 2009 06:31:00 +0000</pubDate>
		<dc:creator>jstrate</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server 2000]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2008]]></category>
		<category><![CDATA[T-SQL]]></category>

		<guid isPermaLink="false">http://www.jasonstrate.com/?p=144</guid>
		<description><![CDATA[A while ago while making changes to a client database, I needed to determine all of the object level permissions that were in the database I was working on.  The system stored procedure sp_helprotect turned out to be pretty useful in obtaining this information. 
The procedure accepts four parameters:


sp_helprotect [ [ @name = ] &#039;object_statement&#039; ]
[ [...]


Related posts:<ol><li><a href='http://www.jasonstrate.com/index.php/2008/11/i-dont-want-to-use-the-object-browser-sp_helptext/' rel='bookmark' title='Permanent Link: I don&#8217;t Want To Use the Object Browser (sp_helptext)'>I don&#8217;t Want To Use the Object Browser (sp_helptext)</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2009/12/does-your-stored-procedure-grant-itself-permissions/' rel='bookmark' title='Permanent Link: Does Your Stored Procedure Grant Itself Permissions?'>Does Your Stored Procedure Grant Itself Permissions?</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2010/02/please-no-trim/' rel='bookmark' title='Permanent Link: Please, no TRIM()?'>Please, no TRIM()?</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.jasonstrate.com%2Findex.php%2F2009%2F01%2Fscripting-object-level-permissions%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.jasonstrate.com%2Findex.php%2F2009%2F01%2Fscripting-object-level-permissions%2F" height="61" width="51" /></a></div><p>A while ago while making changes to a client database, I needed to determine all of the object level permissions that were in the database I was working on.  The system stored procedure sp_helprotect turned out to be pretty useful in obtaining this information. </p>
<p>The procedure accepts four parameters:</p>
<pre class="brush: sql; ">

sp_helprotect [ [ @name = ] &#039;object_statement&#039; ]
[ , [ @username = ] &#039;security_account&#039; ]
[ , [ @grantorname = ] &#039;grantor&#039; ]
[ , [ @permissionarea = ] &#039;type&#039; ]
</pre>
<p>They do pretty much what would be expected.  Provide @name of an object and the results are limited to those for that object only.</p>
<p>Of course, I wasn&#8217;t a huge fan of the output from the procedure since I couldn&#8217;t use it directly to rebuild all of the permissions.  Below is the T-SQL statement that I put together to provide what I needed.</p>
<pre class="brush: sql; ">

SET NOCOUNT ON
GO

DECLARE @Permissions TABLE
(
Owner nvarchar(128)
,Object nvarchar(128)
,Grantee nvarchar(128)
,Grantor nvarchar(128)
,ProtectType nvarchar(10)
,[Action] nvarchar(10)
,[Column] nvarchar(128)
)

INSERT INTO @Permissions
EXEC sp_helprotect

SELECT RTRIM(UPPER(ProtectType)) + Space(1)
   + RTRIM(UPPER([Action])) + Space(1)
   + CASE WHEN Object &lt;&gt; &#039;.&#039; THEN &#039;ON &#039; + QUOTENAME(Owner) + &#039;.&#039; + QUOTENAME(Object)
   + Space(1) ELSE Space(0)
   END
   + CASE WHEN (PATINDEX(&#039;%All%&#039;, [Column]) = 0) and ([Column] &lt;&gt; &#039;.&#039;) THEN &#039; (&#039;
+ [Column] + &#039;)&#039; ELSE Space(0) END
   + &#039;TO &#039; + QUOTENAME(Grantee)
   + CHAR(10) + &#039;GO&#039; + CHAR(10)
FROM @Permissions
ORDER BY CASE WHEN [Action] = &#039;CONNECT&#039; THEN 0 ELSE 1 END, Owner, Object, Grantee
</pre>
<p>Hope this helps anyone with similar needs.</p>


<p>Related posts:<ol><li><a href='http://www.jasonstrate.com/index.php/2008/11/i-dont-want-to-use-the-object-browser-sp_helptext/' rel='bookmark' title='Permanent Link: I don&#8217;t Want To Use the Object Browser (sp_helptext)'>I don&#8217;t Want To Use the Object Browser (sp_helptext)</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2009/12/does-your-stored-procedure-grant-itself-permissions/' rel='bookmark' title='Permanent Link: Does Your Stored Procedure Grant Itself Permissions?'>Does Your Stored Procedure Grant Itself Permissions?</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2010/02/please-no-trim/' rel='bookmark' title='Permanent Link: Please, no TRIM()?'>Please, no TRIM()?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.jasonstrate.com/index.php/2009/01/scripting-object-level-permissions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Last Time SQL Server Restarted</title>
		<link>http://www.jasonstrate.com/index.php/2008/07/last-time-sql-server-restarted/</link>
		<comments>http://www.jasonstrate.com/index.php/2008/07/last-time-sql-server-restarted/#comments</comments>
		<pubDate>Tue, 01 Jul 2008 17:25:00 +0000</pubDate>
		<dc:creator>jstrate</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server 2000]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2008]]></category>
		<category><![CDATA[Tip]]></category>

		<guid isPermaLink="false">http://www.jasonstrate.com/?p=109</guid>
		<description><![CDATA[Not a really hard thing to figure out, but for some crazy reason I always forget.&#160; So, hopefully actually writing it out for the world to see will help me remember. 
Since tempdb is created every time that SQL Server restarts, the created date for that database can be used to determine the last time [...]


Related posts:<ol><li><a href='http://www.jasonstrate.com/index.php/2009/10/checking-exists-whats-your-practice/' rel='bookmark' title='Permanent Link: Checking EXISTS &ndash; What&rsquo;s Your Practice?'>Checking EXISTS &ndash; What&rsquo;s Your Practice?</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2010/03/grouping-and-rounding-dates/' rel='bookmark' title='Permanent Link: Grouping and Rounding Dates'>Grouping and Rounding Dates</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2009/07/5-common-mistakes-with-tempdb/' rel='bookmark' title='Permanent Link: 5 Common Mistakes with Tempdb'>5 Common Mistakes with Tempdb</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.jasonstrate.com%2Findex.php%2F2008%2F07%2Flast-time-sql-server-restarted%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.jasonstrate.com%2Findex.php%2F2008%2F07%2Flast-time-sql-server-restarted%2F" height="61" width="51" /></a></div><p>Not a really hard thing to figure out, but for some crazy reason I always forget.&#160; So, hopefully actually writing it out for the world to see will help me remember. </p>
<p>Since tempdb is created every time that SQL Server restarts, the created date for that database can be used to determine the last time the SQL Server restarted. </p>
<blockquote><p>SELECT create_date FROM sys.databases WHERE name = &#8216;tempdb</p></blockquote>
<p>Yeah&#8230; really hard, hehe.</p>


<p>Related posts:<ol><li><a href='http://www.jasonstrate.com/index.php/2009/10/checking-exists-whats-your-practice/' rel='bookmark' title='Permanent Link: Checking EXISTS &ndash; What&rsquo;s Your Practice?'>Checking EXISTS &ndash; What&rsquo;s Your Practice?</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2010/03/grouping-and-rounding-dates/' rel='bookmark' title='Permanent Link: Grouping and Rounding Dates'>Grouping and Rounding Dates</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2009/07/5-common-mistakes-with-tempdb/' rel='bookmark' title='Permanent Link: 5 Common Mistakes with Tempdb'>5 Common Mistakes with Tempdb</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.jasonstrate.com/index.php/2008/07/last-time-sql-server-restarted/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Incrementing Values</title>
		<link>http://www.jasonstrate.com/index.php/2007/11/incrementing-values/</link>
		<comments>http://www.jasonstrate.com/index.php/2007/11/incrementing-values/#comments</comments>
		<pubDate>Wed, 14 Nov 2007 16:12:00 +0000</pubDate>
		<dc:creator>jstrate</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server 2000]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[T-SQL]]></category>

		<guid isPermaLink="false">http://www.jasonstrate.com/?p=99</guid>
		<description><![CDATA[Occasionally, I run across procedures that mimic the functionality of the IDENTITY property.&#160; There are always various reasons for these procedures to exist, some valid and some not quite so.&#160; Recently while trying to tune one of these procedures that someone had added interesting locking hints to a creative rewrite to the procedure was suggested.
Usually [...]


Related posts:<ol><li><a href='http://www.jasonstrate.com/index.php/2009/02/rounding-up-to-the-nearest-1000/' rel='bookmark' title='Permanent Link: Rounding Up to the Nearest 1,000'>Rounding Up to the Nearest 1,000</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2006/05/this-blog-entry-brought-to-you-by-the-procedure-sp_msforeachdb/' rel='bookmark' title='Permanent Link: This blog entry brought to you by the procedure &quot;sp_MSForEachDB&quot;'>This blog entry brought to you by the procedure &quot;sp_MSForEachDB&quot;</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2009/01/scripting-object-level-permissions/' rel='bookmark' title='Permanent Link: Scripting Object Level Permissions'>Scripting Object Level Permissions</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.jasonstrate.com%2Findex.php%2F2007%2F11%2Fincrementing-values%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.jasonstrate.com%2Findex.php%2F2007%2F11%2Fincrementing-values%2F" height="61" width="51" /></a></div><p>Occasionally, I run across procedures that mimic the functionality of the IDENTITY property.&#160; There are always various reasons for these procedures to exist, some valid and some not quite so.&#160; Recently while trying to tune one of these procedures that someone had added interesting locking hints to a creative rewrite to the procedure was suggested.</p>
<p>Usually these procedure have a SELECT and then an UPDATE in the procedure to get and set the value.&#160; In the suggested solution the OUTPUT variable would be included in the SET statement.&#160; I&#8217;ve attached two sample scripts that includes this type of functionality.&#160; The &quot;IDENTITY_OLD&quot; is the typical way that this is implemented and &quot;IDENTITY_NEW&quot; contains the new method.&#160; The new method is as such:</p>
<blockquote><p>Update Configuration&#160; <br />Set value = value + 1, @ID = value + 1&#160; <br />Where tablename = @tablename</p></blockquote>
<p>This code change hasn&#8217;t been implemented in the test or production environments yet, because I am still early in reviewing this.&#160; I haven&#8217;t been able to find anything wrong with this yet and maybe there isn&#8217;t anything to fear.&#160; A few searches on the internet hasn&#8217;t turned up anything that resembles the solution, so I ask&#8230; does anyone see anything wrong with this?</p>
<p>EDITED: Better scripts make better examples.</p>


<p>Related posts:<ol><li><a href='http://www.jasonstrate.com/index.php/2009/02/rounding-up-to-the-nearest-1000/' rel='bookmark' title='Permanent Link: Rounding Up to the Nearest 1,000'>Rounding Up to the Nearest 1,000</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2006/05/this-blog-entry-brought-to-you-by-the-procedure-sp_msforeachdb/' rel='bookmark' title='Permanent Link: This blog entry brought to you by the procedure &quot;sp_MSForEachDB&quot;'>This blog entry brought to you by the procedure &quot;sp_MSForEachDB&quot;</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2009/01/scripting-object-level-permissions/' rel='bookmark' title='Permanent Link: Scripting Object Level Permissions'>Scripting Object Level Permissions</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.jasonstrate.com/index.php/2007/11/incrementing-values/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Microsoft Certification Second Shot Exam, It&#8217;s Back&#8230;</title>
		<link>http://www.jasonstrate.com/index.php/2007/09/microsoft-certification-second-shot-exam-its-back/</link>
		<comments>http://www.jasonstrate.com/index.php/2007/09/microsoft-certification-second-shot-exam-its-back/#comments</comments>
		<pubDate>Fri, 21 Sep 2007 15:24:00 +0000</pubDate>
		<dc:creator>jstrate</dc:creator>
				<category><![CDATA[Certification]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server 2000]]></category>
		<category><![CDATA[SQL Server 2005]]></category>

		<guid isPermaLink="false">http://www.jasonstrate.com/?p=95</guid>
		<description><![CDATA[It turns out that the Microsoft Certfication Second Shot Exam (FAQ) is back&#8230; 
For a limited time, you can get a free, second shot at any IT professional, developer, or Microsoft Dynamics certification exam. Just register for this offer before your first exam, and you will get two chances to pass. But this offer won&#8217;t [...]


Related posts:<ol><li><a href='http://www.jasonstrate.com/index.php/2006/02/microsoft-certification-second-shot-exam/' rel='bookmark' title='Permanent Link: Microsoft Certification Second Shot Exam'>Microsoft Certification Second Shot Exam</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2009/10/sql-server-certification-discounts/' rel='bookmark' title='Permanent Link: SQL Server Certification Discounts'>SQL Server Certification Discounts</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2008/08/second-shot-exams/' rel='bookmark' title='Permanent Link: Second Shot Exams&#8230;'>Second Shot Exams&#8230;</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.jasonstrate.com%2Findex.php%2F2007%2F09%2Fmicrosoft-certification-second-shot-exam-its-back%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.jasonstrate.com%2Findex.php%2F2007%2F09%2Fmicrosoft-certification-second-shot-exam-its-back%2F" height="61" width="51" /></a></div><p>It turns out that the <a href="http://www.microsoft.com/learning/mcp/offers/secondshot/default.mspx">Microsoft Certfication Second Shot Exam</a> (<a href="http://www.microsoft.com/learning/mcp/offers/secondshot/faq/default.mspx">FAQ</a>) is back&#8230; </p>
<blockquote><p><em>For a limited time, you can get a free, second shot at any IT professional, developer, or Microsoft Dynamics certification exam. Just register for this offer before your first exam, and you will get two chances to pass. But this offer won&#8217;t last forever.</em></p>
</blockquote>
<p>The limited time is September 15, 2007, and January 30, 2008, so there is plenty of time to cram and exam.&#160; The nice thing is this isn&#8217;t limited to a single exam, you can get a voucher for any and all exams taken while through January.</p>
<p>This is pretty great, almost as good as playing Halo 3 will be next Tuesday.&#160; Riiiight!</p>


<p>Related posts:<ol><li><a href='http://www.jasonstrate.com/index.php/2006/02/microsoft-certification-second-shot-exam/' rel='bookmark' title='Permanent Link: Microsoft Certification Second Shot Exam'>Microsoft Certification Second Shot Exam</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2009/10/sql-server-certification-discounts/' rel='bookmark' title='Permanent Link: SQL Server Certification Discounts'>SQL Server Certification Discounts</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2008/08/second-shot-exams/' rel='bookmark' title='Permanent Link: Second Shot Exams&#8230;'>Second Shot Exams&#8230;</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.jasonstrate.com/index.php/2007/09/microsoft-certification-second-shot-exam-its-back/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>This blog entry brought to you by the procedure &quot;sp_MSForEachDB&quot;</title>
		<link>http://www.jasonstrate.com/index.php/2006/05/this-blog-entry-brought-to-you-by-the-procedure-sp_msforeachdb/</link>
		<comments>http://www.jasonstrate.com/index.php/2006/05/this-blog-entry-brought-to-you-by-the-procedure-sp_msforeachdb/#comments</comments>
		<pubDate>Tue, 09 May 2006 16:21:00 +0000</pubDate>
		<dc:creator>jstrate</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server 2000]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[T-SQL]]></category>

		<guid isPermaLink="false">http://www.jasonstrate.com/?p=31</guid>
		<description><![CDATA[My undocumented stored procedure of the day is sp_MSForEachDB. This procedure allows SQL statments to loop through all database names on a server with a dynamic SQL string. The procedure accepts the variable @command1 for the dynamic SQL string, and the database name is passed into the string through the use of &#34;?&#34;. Unlike using [...]


Related posts:<ol><li><a href='http://www.jasonstrate.com/index.php/2009/12/does-your-stored-procedure-grant-itself-permissions/' rel='bookmark' title='Permanent Link: Does Your Stored Procedure Grant Itself Permissions?'>Does Your Stored Procedure Grant Itself Permissions?</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2006/05/room-with-a-view/' rel='bookmark' title='Permanent Link: Room with a View'>Room with a View</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2009/01/scripting-object-level-permissions/' rel='bookmark' title='Permanent Link: Scripting Object Level Permissions'>Scripting Object Level Permissions</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.jasonstrate.com%2Findex.php%2F2006%2F05%2Fthis-blog-entry-brought-to-you-by-the-procedure-sp_msforeachdb%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.jasonstrate.com%2Findex.php%2F2006%2F05%2Fthis-blog-entry-brought-to-you-by-the-procedure-sp_msforeachdb%2F" height="61" width="51" /></a></div><p>My undocumented stored procedure of the day is <b>sp_MSForEachDB</b>. This procedure allows SQL statments to loop through all database names on a server with a dynamic SQL string. The procedure accepts the variable <b>@command1</b> for the dynamic SQL string, and the database name is passed into the string through the use of &quot;?&quot;. Unlike using the sp_ExecuteSQL you are able build the SQL string</p>
<p>One thing to note with this stored procedure is that is does not switch contexts while it executes. So all of the SQL statements will run in the context of the master database. Getting around this issue is fairly trivial using either three-part naming of database objects or through the <b>USE</b> command.</p>
<p>For example executing sp_HelpDB for each database can be achieved through three-part naming:</p>
<blockquote><p>sp_MSForEachDB &#8216;?..sp_HelpDB&#8217;</p>
</blockquote>
<p> or the USE command<br />
<blockquote>
<p>sp_MSForEachDB &#8216;Use ? exec sp_HelpDB&#8217;</p>
</blockquote>
<p> The sp_HelpDB can be quite useful, I recently ran a script similar to the one below to get a list of IDs that appeared in a table in all of our client databases.<br />
<blockquote>Create Table #Foo   <br />(    <br />DBName sysname,    <br />FooType varchar(20),    <br />FooID varchar(20)    <br />)    <br />Exec sp_MSForEachDB &#8216;Use ? If Object_ID(&#8221;Foo&#8221;) Is NOT NULL Insert Into #Foo Select &#8221;?&#8221;, FooType, FooID From Foo&#8217;    <br />Select * From #Foo</p></blockquote>
<p> Hope this helps the many (or few rather) people that read this.</p>


<p>Related posts:<ol><li><a href='http://www.jasonstrate.com/index.php/2009/12/does-your-stored-procedure-grant-itself-permissions/' rel='bookmark' title='Permanent Link: Does Your Stored Procedure Grant Itself Permissions?'>Does Your Stored Procedure Grant Itself Permissions?</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2006/05/room-with-a-view/' rel='bookmark' title='Permanent Link: Room with a View'>Room with a View</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2009/01/scripting-object-level-permissions/' rel='bookmark' title='Permanent Link: Scripting Object Level Permissions'>Scripting Object Level Permissions</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.jasonstrate.com/index.php/2006/05/this-blog-entry-brought-to-you-by-the-procedure-sp_msforeachdb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Room with a View</title>
		<link>http://www.jasonstrate.com/index.php/2006/05/room-with-a-view/</link>
		<comments>http://www.jasonstrate.com/index.php/2006/05/room-with-a-view/#comments</comments>
		<pubDate>Sat, 06 May 2006 15:00:00 +0000</pubDate>
		<dc:creator>jstrate</dc:creator>
				<category><![CDATA[Performance Tuning]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server 2000]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2008]]></category>

		<guid isPermaLink="false">http://www.jasonstrate.com/?p=29</guid>
		<description><![CDATA[Every so often someone will get me on the topic of why &#34;Select *&#34; is an official Bad Practice. There are various arguements against &#34;Select *&#34; but one that a lot of programmers may not be aware of is the relationship between &#34;Select *&#34; and views.
When a view is created with &#34;Select *&#34; it references [...]


Related posts:<ol><li><a href='http://www.jasonstrate.com/index.php/2010/02/please-no-trim/' rel='bookmark' title='Permanent Link: Please, no TRIM()?'>Please, no TRIM()?</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2010/06/index-those-foreign-keys/' rel='bookmark' title='Permanent Link: Index Those Foreign Keys'>Index Those Foreign Keys</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2008/07/last-time-sql-server-restarted/' rel='bookmark' title='Permanent Link: Last Time SQL Server Restarted'>Last Time SQL Server Restarted</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.jasonstrate.com%2Findex.php%2F2006%2F05%2Froom-with-a-view%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.jasonstrate.com%2Findex.php%2F2006%2F05%2Froom-with-a-view%2F" height="61" width="51" /></a></div><p>Every so often someone will get me on the topic of why &quot;Select *&quot; is an official <b>Bad Practice</b>. There are various arguements against &quot;Select *&quot; but one that a lot of programmers may not be aware of is the relationship between &quot;Select *&quot; and views.</p>
<p>When a view is created with &quot;Select *&quot; it references the tables that are part of the view and creates metadata to translate &quot;Select *&quot; into a listing of the columns that the view needs to retrieve. While this is a way to get around the work of typing out the columns for the result set there are unintended circumstances that can occur.   <br />For an example, create the following table and view:</p>
<blockquote><p><i>create table tbl_foo ([roo] int, [too] int, [moo] int)     <br />create view vw_foo as select * from tbl_foo</i></p></blockquote>
<p> If select from this view, you&#8217;ll get a list back of all of the columns in the table as expected. Now alter the table to include an additional column, such as:<br />
<blockquote><i>alter table tbl_foo add [BOO] int</i></p></blockquote>
<p>Now when you select from the view only the columns roo, too, and moo will return. The column BOO is <b>not</b> included in the select list. As I mentioned before when a view is created, SQL Server obtains metadata about to define what columns &quot;Select *&quot; references. In order to return the columns BOO in the view, the metadata needs to be refreshed. SQL Server does include a stored procedure, the procedure sp_refreshview will refresh the metadata of the view.<br />
<blockquote>exec sp_refreshview &#8216;vw_foo&#8217;</p></blockquote>
<p> Select from the view now will return all of the columns from the table.&#160; <br />Being able to fix the metadata issue that table schema changes cause to &quot;Select *&quot; views doesn&#8217;t offset the additional step required to go in after the fact table changes and refresh each affected view. Views need to return specific sets of data, be naming the columns that are returned mistakes can be avoided that might sentance you to <a href="http://thedailywtf.com/">WTF</a>.  <br />I can imagine the guy who avoids refreshing views to prevent new columns from returning in the views. Then one day someone updates the sales table and refreshes the view, and suddenly the CEO wants to know why there are credit card numbers on the corporate website.</p>


<p>Related posts:<ol><li><a href='http://www.jasonstrate.com/index.php/2010/02/please-no-trim/' rel='bookmark' title='Permanent Link: Please, no TRIM()?'>Please, no TRIM()?</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2010/06/index-those-foreign-keys/' rel='bookmark' title='Permanent Link: Index Those Foreign Keys'>Index Those Foreign Keys</a></li>
<li><a href='http://www.jasonstrate.com/index.php/2008/07/last-time-sql-server-restarted/' rel='bookmark' title='Permanent Link: Last Time SQL Server Restarted'>Last Time SQL Server Restarted</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.jasonstrate.com/index.php/2006/05/room-with-a-view/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
