<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlblog.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Search results matching tags 'Best Practices' and 'future-proofing'</title><link>http://sqlblog.com/search/SearchResults.aspx?o=DateDescending&amp;tag=Best+Practices,future-proofing&amp;orTags=0</link><description>Search results matching tags 'Best Practices' and 'future-proofing'</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>Bad habits to kick : ORDER BY ordinal</title><link>http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/06/bad-habits-to-kick-order-by-ordinal.aspx</link><pubDate>Tue, 06 Oct 2009 14:49:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:17313</guid><dc:creator>AaronBertrand</dc:creator><description>&lt;p&gt;&lt;i&gt;A few weeks ago, I wrote a post about forming a new habit: &lt;a href="http://sqlblog.com/blogs/aaron_bertrand/archive/2009/09/03/ladies-and-gentlemen-start-your-semi-colons.aspx" title="http://sqlblog.com/blogs/aaron_bertrand/archive/2009/09/03/ladies-and-gentlemen-start-your-semi-colons.aspx" target="_blank"&gt;always terminate statements with semi-colons&lt;/a&gt;.&amp;nbsp; Today I thought I would start a series on kicking bad habits that many of us have developed over time.&amp;nbsp; I provided a little more background on this series &lt;a href="http://bit.ly/1dZv6G" title="http://www.onetooneinteractive.com/otolabs-posts/2009/10/10/helping-people-kick-bad-sql-server-habits/" target="_blank"&gt;over on my company's site&lt;/a&gt;.&amp;nbsp; Today's topic: using ordinal numbers in our ORDER BY clauses.&amp;nbsp; &lt;/i&gt;&lt;/p&gt;&lt;p&gt;At least once a week, I catch myself using ordinal position to define order.&amp;nbsp; For example, I might have this:&amp;nbsp; &lt;br&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;table cellpadding="0" cellspacing="0" bgcolor="#eeeeee"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre style="padding:10px 20px;-moz-background-clip:border;-moz-background-origin:padding;font-size:12px;font-family:consolas,lucida console,courier new,courier;-moz-background-inline-policy:continuous;"&gt;&lt;font color="blue"&gt;SELECT&amp;nbsp;&lt;/font&gt;&lt;font color="black"&gt;foo&lt;/font&gt;&lt;font color="gray"&gt;,&amp;nbsp;&lt;/font&gt;&lt;font color="black"&gt;bar&lt;br&gt;&lt;/font&gt;&lt;font color="blue"&gt;  FROM&amp;nbsp;&lt;/font&gt;&lt;font color="black"&gt;dbo.splunge&lt;br&gt;&lt;/font&gt;&lt;font color="blue"&gt;  ORDER&amp;nbsp;BY&amp;nbsp;&lt;/font&gt;&lt;font color="black"&gt;1&lt;/font&gt;&lt;font color="gray"&gt;,&amp;nbsp;&lt;/font&gt;&lt;font color="black"&gt;2&amp;nbsp;&lt;/font&gt;&lt;font color="blue"&gt;DESC&lt;/font&gt;&lt;font color="gray"&gt;;&lt;/font&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is lazy shorthand, and is bound to get screwed up at some point unless I have encrypted the stored procedure and threw away the key.&amp;nbsp; Invariably, someone at some point is going to come in and add a column, remove a column, or change the order of the columns.&lt;br&gt;&lt;/p&gt;

&lt;p&gt;Remember that a lot of us produce stored procedures to be consumed by essentially "dumb" clients - Windows forms or web applications that lack the ability to perform any ordering on their own.&amp;nbsp; So often the ORDER BY clause of a resultset coming back from a stored procedure is pretty important.&amp;nbsp; When editing a stored procedure that has an error-prone ORDER BY clause like the above, it is very easy to make changes to the SELECT list without even looking at the ORDER BY clause, or the reverse.&amp;nbsp; Imagine the web developer using the above procedure asks to change the SELECT list.&amp;nbsp; Now he wants mort, foo, bar.&amp;nbsp; (Note that order of the columns themselves should be irrelevant to the application, since it should be using column name and not ordinal references, but in some cases we like certain columns to appear in a certain order when we are debugging in SSMS and the like.)&amp;nbsp; So assume you do exactly as the developer asks, and edit the SELECT clause and alter the procedure:&lt;/p&gt;


&lt;blockquote&gt;
&lt;table cellpadding="0" cellspacing="0" bgcolor="#eeeeee"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre style="padding:10px 20px;-moz-background-clip:border;-moz-background-origin:padding;font-size:12px;font-family:consolas,lucida console,courier new,courier;-moz-background-inline-policy:continuous;"&gt;&lt;font color="blue"&gt;SELECT&amp;nbsp;&lt;/font&gt;mort, &lt;font color="black"&gt;foo&lt;/font&gt;&lt;font color="gray"&gt;,&amp;nbsp;&lt;/font&gt;&lt;font color="black"&gt;bar&lt;br&gt;&lt;/font&gt;&lt;font color="blue"&gt;  FROM&amp;nbsp;&lt;/font&gt;&lt;font color="black"&gt;dbo.splunge&lt;br&gt;&lt;/font&gt;&lt;font color="blue"&gt;  ORDER&amp;nbsp;BY&amp;nbsp;&lt;/font&gt;&lt;font color="black"&gt;1&lt;/font&gt;&lt;font color="gray"&gt;,&amp;nbsp;&lt;/font&gt;&lt;font color="black"&gt;2&amp;nbsp;&lt;/font&gt;&lt;font color="blue"&gt;DESC&lt;/font&gt;&lt;font color="gray"&gt;;&lt;/font&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/blockquote&gt;

&lt;p&gt;Oops!&amp;nbsp; Now the developer is complaining that his UI is broken because the order is all messed up.&amp;nbsp; This would not have happened if you had used the following syntax in the first place:&lt;/p&gt;

&lt;blockquote&gt;
&lt;table cellpadding="0" cellspacing="0" bgcolor="#eeeeee"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre style="padding:10px 20px;-moz-background-clip:border;-moz-background-origin:padding;font-size:12px;font-family:consolas,lucida console,courier new,courier;-moz-background-inline-policy:continuous;"&gt;&lt;font color="blue"&gt;SELECT&amp;nbsp;&lt;/font&gt;mort, &lt;font color="black"&gt;foo&lt;/font&gt;&lt;font color="gray"&gt;,&amp;nbsp;&lt;/font&gt;&lt;font color="black"&gt;bar&lt;br&gt;&lt;/font&gt;&lt;font color="blue"&gt;  FROM&amp;nbsp;&lt;/font&gt;&lt;font color="black"&gt;dbo.splunge&lt;br&gt;&lt;/font&gt;&lt;font color="blue"&gt;  ORDER&amp;nbsp;BY&amp;nbsp;&lt;/font&gt;&lt;font color="black"&gt;foo&lt;/font&gt;&lt;font color="gray"&gt;,&amp;nbsp;&lt;/font&gt;&lt;font color="black"&gt;bar&amp;nbsp;&lt;/font&gt;&lt;font color="blue"&gt;DESC&lt;/font&gt;&lt;font color="gray"&gt;;&lt;/font&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/blockquote&gt;

&lt;p&gt;I know it is hard to spell out those column names when you're doing ad
hoc stuff, but getting in the habit will potentially save your bacon
someday.&amp;nbsp; And you can't use the excuse that you have very complicated expressions in your SELECT list, because ORDER BY is the only place in the entire query where you can reference an alias you provided.&amp;nbsp; So the following is completely legal:&lt;/p&gt;

&lt;blockquote&gt;
&lt;table cellpadding="0" cellspacing="0" bgcolor="#eeeeee"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre style="padding:10px 20px;-moz-background-clip:border;-moz-background-origin:padding;font-size:12px;font-family:consolas,lucida console,courier new,courier;-moz-background-inline-policy:continuous;"&gt;&lt;font color="blue"&gt;SELECT&amp;nbsp;&lt;/font&gt;&lt;font color="black"&gt;foo&amp;nbsp;&lt;/font&gt;&lt;font color="blue"&gt;=&amp;nbsp;&lt;/font&gt;&lt;font color="magenta"&gt;RTRIM&lt;/font&gt;&lt;font color="gray"&gt;(&lt;/font&gt;&lt;font color="magenta"&gt;CONVERT&lt;/font&gt;&lt;font color="gray"&gt;(&lt;/font&gt;&lt;font color="blue"&gt;INT&lt;/font&gt;&lt;font color="gray"&gt;,&amp;nbsp;&lt;/font&gt;&lt;font color="magenta"&gt;ABS&lt;/font&gt;&lt;font color="gray"&gt;(&lt;/font&gt;&lt;font color="black"&gt;foo&lt;/font&gt;&lt;font color="gray"&gt;) % 2))&lt;br&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="blue"&gt;FROM&amp;nbsp;&lt;/font&gt;&lt;font color="black"&gt;dbo.splunge&lt;br&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="blue"&gt;ORDER&amp;nbsp;BY &lt;/font&gt;&lt;font color="black"&gt;foo&lt;/font&gt;&lt;font color="gray"&gt;;&lt;/font&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/blockquote&gt;

&lt;p&gt;There is nothing lost by being explicit, except for a few keystrokes.&amp;nbsp; But there is plenty to lose by not doing so - including some patience for the developer running to your cube like their head is on fire.&amp;nbsp; Ideally, when you are making changes to existing code, you examine the entire statement to ensure consistency.&amp;nbsp; But try to be proactive and protect yourself against the inevitable rushed and possibly botched emergency fix.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&lt;i&gt;I am working on a series of "Bad habits to kick" articles, in an effort to motivate people to drop some of the things that I hate to see when I inherit code.&amp;nbsp; Up next: &lt;a href="http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/07/bad-habits-to-kick-using-a-loop-to-populate-a-table.aspx" title="http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/07/bad-habits-to-kick-using-a-loop-to-populate-a-table.aspx" target="_blank"&gt;using loops to populate large tables&lt;/a&gt;. &lt;/i&gt;&lt;br&gt;&lt;/p&gt;</description></item><item><title>Ladies and gentlemen, start your semi-colons!</title><link>http://sqlblog.com/blogs/aaron_bertrand/archive/2009/09/03/ladies-and-gentlemen-start-your-semi-colons.aspx</link><pubDate>Thu, 03 Sep 2009 17:13:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:16567</guid><dc:creator>AaronBertrand</dc:creator><description>Almost a year ago now, I &lt;a href="http://sqlblog.com/blogs/aaron_bertrand/archive/2008/10/30/my-stored-procedure-best-practices-checklist.aspx" title="http://sqlblog.com/blogs/aaron_bertrand/archive/2008/10/30/my-stored-procedure-best-practices-checklist.aspx" target="_blank"&gt;wrote up a blog post&lt;/a&gt; detailing the things that I strive to do when writing T-SQL modules (mostly stored procedures).&amp;nbsp; One of the things that I have been doing since my very first common table expression (CTE) back in the Yukon beta is ending all relevant statements with statement terminators (semi-colons).&amp;nbsp; A few responses to the above post indicated that they don't currently use statement terminators, and had no interest in starting.&amp;nbsp; Let's quickly recap the reasons why I started making this a habit.&lt;br&gt;&amp;nbsp; &lt;br&gt;
&lt;p&gt;&lt;font size="3"&gt;&lt;b&gt;Today, I use CTEs and Service Broker.&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;/p&gt;


&lt;p&gt;Unless it is the first statement in a batch, the previous statement prior to a CTE declaration needs to be terminated with a semi-colon.&amp;nbsp; This is also true for Service Broker commands (e.g. SEND ON CONVERSATION).&amp;nbsp; Some people "fix" this by simply writing code ike this: &lt;br&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;table bgcolor="#eeeeee" cellpadding="0" cellspacing="0"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre style="padding:10px 20px;-moz-background-clip:border;-moz-background-origin:padding;font-size:12px;font-family:consolas,lucida console,courier new,courier;-moz-background-inline-policy:continuous;"&gt;&lt;font color="gray"&gt;;&lt;/font&gt;&lt;font color="blue"&gt;WITH&lt;/font&gt; foo &lt;font color="blue"&gt;AS&lt;/font&gt; &lt;font color="gray"&gt;(...) ...&lt;/font&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/blockquote&gt;

&lt;p&gt;And typically when I post CTE examples to newsgroups / forums, I do this, to avoid the inevitable comeback with this error message attached (because you never know where they are going to jam your example, and then complain that it didn't work):&lt;/p&gt;


&lt;blockquote&gt;
&lt;table bgcolor="#eeeeee" cellpadding="0" cellspacing="0"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre style="padding:10px 20px;-moz-background-clip:border;-moz-background-origin:padding;font-size:12px;font-family:consolas,lucida console,courier new,courier;-moz-background-inline-policy:continuous;"&gt;&lt;font color="#cc0000"&gt;.Net SqlClient Data Provider: Msg 319, Level 15, State 1, Line 2&lt;br&gt;Incorrect syntax near the keyword 'with'. If this statement is a common table expression&lt;br&gt;or an xmlnamespaces clause, the previous statement must be terminated with a semicolon&lt;/font&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/blockquote&gt;

&lt;p&gt;But I think that syntax is far too ugly and counter-intuitive for my production code (YMMV).&amp;nbsp; So for this reason, all relevant statements in my code get a semi-colon.&amp;nbsp; I didn't
go to the extent of inspecting all of my existing code and adding them, but if I was re-visiting a module for some other enhancement, I would take the few seconds and add any semi-colons that were missing.&amp;nbsp; I didn't feel like I needed to do this, but thought it best to future-proof my code as much as possible, when convenient.&amp;nbsp; And of course when writing new code, I would always terminate.&amp;nbsp; This is probably best demonstrated by scrolling through my blog posts over the past year or two, and trying to spot any examples where I neglected to add a semi-colon.&amp;nbsp; I doubt you'll find many!&lt;br&gt;&amp;nbsp; &lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3"&gt;&lt;b&gt;Someday, I may use MERGE.&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;In SQL Server 2008, a similar requirement was added for MERGE: you can't run a MERGE statement unless it is properly terminated with a semi-colon.&amp;nbsp; Otherwise, you get this error message:&lt;/p&gt;

&lt;blockquote&gt;
&lt;table bgcolor="#eeeeee" cellpadding="0" cellspacing="0"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre style="padding:10px 20px;-moz-background-clip:border;-moz-background-origin:padding;font-size:12px;font-family:consolas,lucida console,courier new,courier;-moz-background-inline-policy:continuous;"&gt;&lt;font color="#cc0000"&gt;.Net SqlClient Data Provider: Msg 10713, Level 15, State 1, Line 21&lt;br&gt;A MERGE statement must be terminated by a semi-colon (;)&lt;/font&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/blockquote&gt;

&lt;p&gt;So because of this, the set of reasons for future-proofing your code in this way has doubled: while your CTEs and MERGE statements obviously work today, because your procedure compiled, a user modifying them later might break them, and this will cause an extra debugging step.&amp;nbsp; So at this point, I was debating whether it might make sense to comb through all of my code and add semi-colons where appropriate, but was still sitting quite squarely on the fence.&lt;br&gt;&amp;nbsp; &lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3"&gt;&lt;b&gt;Not convinced?&amp;nbsp; Hold on, there's more!&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;a href="http://sqlblog.com/blogs/aaron_bertrand/archive/2008/10/30/my-stored-procedure-best-practices-checklist.aspx" title="http://sqlblog.com/blogs/aaron_bertrand/archive/2008/10/30/my-stored-procedure-best-practices-checklist.aspx" target="_blank"&gt;previous post&lt;/a&gt;, I suggested that someday Microsoft will make statement terminators mandatory.&amp;nbsp; Well, they have.&amp;nbsp; Statements that DON'T end with a proper statement terminator are on the deprecation list, which means that at some point, any statement that doesn't end with a semi-colon will cause an error similar to those listed above.&amp;nbsp; Sounds funny, but it is true.&amp;nbsp; If you don't believe me, please review these topics in Books Online:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Transact-SQL Syntax Conventions (Transact-SQL)&lt;br&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms177563.aspx" title="http://msdn.microsoft.com/en-us/library/ms177563.aspx" target="_blank"&gt;http://msdn.microsoft.com/en-us/library/ms177563.aspx&lt;/a&gt;&lt;br&gt;(See the second-last row in the first table.)&lt;/p&gt;

&lt;p&gt;Deprecated Database Engine Features in SQL Server 2008&lt;br&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms143729.aspx" title="http://msdn.microsoft.com/en-us/library/ms143729.aspx" target="_blank"&gt;http://msdn.microsoft.com/en-us/library/ms143729.aspx&lt;/a&gt;&lt;br&gt;(It's a lot of scrolling; search the page for "semicolon.")&lt;br&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'm not sure if they're doing this because the ANSI standard now declares statement terminators as mandatory, or because as the T-SQL language gets more and more complex, the complexities in the parser code multiply, or a combination of both.&amp;nbsp; But I am no longer on the fence: it is on my "long-term task list" to systematically attack chunks of T-SQL modules and fix these pesky situations where statement terminators are missing.&lt;br&gt;&amp;nbsp; &lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="3"&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;I've outlined several good reasons to get into the habit of ending all of your T-SQL statements with semi-colons, at least for work going forward.&amp;nbsp; And I may have even painted a picture that shows you it may worthwhile to go back and "fix" your existing codebase -- maybe coupled with a simultaneous code review of some other kind, to help justify the effort.&amp;nbsp; Because "a future version of SQL Server" might be closer than you think.&lt;/p&gt;

&lt;p&gt;[Hmm, now I'm thinking the title of this post sounds a little dirty.]&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description></item></channel></rss>