<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://strangenut.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">SQL Server Blog</title><subtitle type="html">Performance, troubleshooting, programming and maintenance tips for Microsoft SQL Server 2000-2008</subtitle><id>http://strangenut.com/blogs/dacrowlah/atom.aspx</id><link rel="alternate" type="text/html" href="http://strangenut.com/blogs/dacrowlah/default.aspx" /><link rel="self" type="application/atom+xml" href="http://strangenut.com/blogs/dacrowlah/atom.aspx" /><generator uri="http://communityserver.org" version="4.0.30619.63">Community Server</generator><updated>2008-06-24T12:28:00Z</updated><entry><title>How To Use Index Hints in SQL Server 2005 and 2008</title><link rel="alternate" type="text/html" href="/blogs/dacrowlah/archive/2010/03/29/how-to-use-index-hints-in-sql-server-2005-and-2008.aspx" /><id>/blogs/dacrowlah/archive/2010/03/29/how-to-use-index-hints-in-sql-server-2005-and-2008.aspx</id><published>2010-03-29T18:17:00Z</published><updated>2010-03-29T18:17:00Z</updated><content type="html">&lt;p&gt;Sometimes the SQL Server query optimizer does not pick the best index to use in a join operation.&amp;nbsp; This can be caused by a multitude of factors (out of date statistics, wrong indexing strategy for a table, etc) ... for what ever reason it happens, there is a way to force SQL Server to pick the correct index at runtime.&amp;nbsp; This is called an INDEX HINT; if you have ever used a table hint, this is similar to one of those.&amp;nbsp; The syntax is fairly simple, immediately proceeding the table being named in the join, you type&amp;nbsp; &lt;i&gt;with(index(INDEX_NAME))&lt;/i&gt; and this tells SQL Server that when it comes time to join this table in, the named index must be used.&lt;/p&gt;
&lt;p&gt;Below is a sample, previously the execution plan for this query was using a compound query that had OrgId as the first named column.&amp;nbsp; Use of this index was making SQL Server do an Index Scan and then a Hash Join.&amp;nbsp; After adding the index hint it was using the right index and doing a Clustered Index Seek and Nested Inner Loop Join.&amp;nbsp; Perfect.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;alter&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &lt;span style="color:blue;"&gt;view&lt;/span&gt; OrgProductsView &lt;span style="color:blue;"&gt;as&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;select&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; [OrgCatalogs]&lt;span style="color:gray;"&gt;.&lt;/span&gt;[OrgId]&lt;span style="color:gray;"&gt;,&lt;/span&gt; [Products]&lt;span style="color:gray;"&gt;.&lt;/span&gt;[ProductId]&lt;span style="color:gray;"&gt;,&lt;/span&gt; [Catalogs]&lt;span style="color:gray;"&gt;.&lt;/span&gt;[CatalogId]&lt;span style="color:gray;"&gt;,&lt;/span&gt; [Catalogs]&lt;span style="color:gray;"&gt;.&lt;/span&gt;[CatalogTypeId]&lt;span style="color:gray;"&gt;,&lt;/span&gt; [AdjustedPrice]&lt;span style="color:gray;"&gt;,&lt;/span&gt; [ProductTypeId]&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp; &lt;span style="color:blue;"&gt;from&lt;/span&gt; [OrgCatalogs] &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&lt;span style="color:gray;"&gt;inner&lt;/span&gt; &lt;span style="color:gray;"&gt;join&lt;/span&gt; [Catalogs] &lt;span style="color:blue;"&gt;on&lt;/span&gt; [OrgCatalogs]&lt;span style="color:gray;"&gt;.&lt;/span&gt;[CatalogId] &lt;span style="color:gray;"&gt;=&lt;/span&gt; [Catalogs]&lt;span style="color:gray;"&gt;.&lt;/span&gt;[CatalogId]&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&lt;span style="color:gray;"&gt;inner&lt;/span&gt; &lt;span style="color:gray;"&gt;join&lt;/span&gt; [CatalogProducts] &lt;span style="color:blue;"&gt;on&lt;/span&gt; [Catalogs]&lt;span style="color:gray;"&gt;.&lt;/span&gt;[CatalogId] &lt;span style="color:gray;"&gt;=&lt;/span&gt; [CatalogProducts]&lt;span style="color:gray;"&gt;.&lt;/span&gt;[CatalogId]&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&lt;span style="color:gray;"&gt;inner&lt;/span&gt; &lt;span style="color:gray;"&gt;join&lt;/span&gt; [Products] &lt;span style="color:blue;"&gt;with&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;index&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;IX_Products_ProductId&lt;span style="color:gray;"&gt;))&lt;/span&gt; &lt;span style="color:blue;"&gt;on&lt;/span&gt; [CatalogProducts]&lt;span style="color:gray;"&gt;.&lt;/span&gt;[ProductId] &lt;span style="color:gray;"&gt;=&lt;/span&gt; [Products]&lt;span style="color:gray;"&gt;.&lt;/span&gt;[ProductId] &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://strangenut.com/aggbug.aspx?PostID=55" width="1" height="1"&gt;</content><author><name>dacrowlah</name><uri>http://strangenut.com/members/dacrowlah/default.aspx</uri></author><category term="query execution plans" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/query+execution+plans/default.aspx" /><category term="T-SQL" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/T-SQL/default.aspx" /><category term="performance tuning" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/performance+tuning/default.aspx" /><category term="SQL Server" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/SQL+Server/default.aspx" /><category term="Indexes" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/Indexes/default.aspx" /><category term="tips and tricks" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/tips+and+tricks/default.aspx" /></entry><entry><title>How to select only the date part of a datetime field in SQL (SQL Server 2000/2005/2008)</title><link rel="alternate" type="text/html" href="/blogs/dacrowlah/archive/2010/01/28/how-to-select-only-the-date-part-of-a-datetime-field-in-sql-sql-server-2000-2005-2008.aspx" /><id>/blogs/dacrowlah/archive/2010/01/28/how-to-select-only-the-date-part-of-a-datetime-field-in-sql-sql-server-2000-2005-2008.aspx</id><published>2010-01-29T05:19:00Z</published><updated>2010-01-29T05:19:00Z</updated><content type="html">&lt;p&gt;Have you ever needed to get only the date part out of a datetime field in SQL and wanted to drop the precision of the timepart?&amp;nbsp; It&amp;#39;s actually surprisingly easy, and with this method is pretty fast as well. I&amp;#39;ve had to do this many times but always forget the syntax in T-SQL (though this should also work on other database platforms as well) so I figured I would put it up here on the blog and hopefully it would come in handy for some of you guys as well!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;SELECT &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:gray;"&gt;(&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:fuchsia;"&gt;CAST&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:gray;"&gt;(&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:fuchsia;"&gt;FLOOR&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:gray;"&gt;(&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:fuchsia;"&gt;CAST&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:gray;"&gt;(&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:fuchsia;"&gt;GETDATE&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:gray;"&gt;()&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &lt;span style="color:blue;"&gt;AS&lt;/span&gt; &lt;span style="color:blue;"&gt;FLOAT&lt;/span&gt;&lt;span style="color:gray;"&gt;))&lt;/span&gt; &lt;span style="color:blue;"&gt;AS&lt;/span&gt; &lt;span style="color:blue;"&gt;DATETIME&lt;/span&gt;&lt;span style="color:gray;"&gt;))&lt;/span&gt; &lt;span style="color:blue;"&gt;AS&lt;/span&gt; CurrentDate&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;You can, of couse, replace the call to getdate() with a column from a table that you are selecting from and it will work just as well.&amp;nbsp; The performance hit for using this method is neglible ... especially considering the alternative of casting the calling YEAR(), MONTH() and DAY() on the field and concatenating them back together as strings.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://strangenut.com/aggbug.aspx?PostID=53" width="1" height="1"&gt;</content><author><name>dacrowlah</name><uri>http://strangenut.com/members/dacrowlah/default.aspx</uri></author><category term="T-SQL" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/T-SQL/default.aspx" /><category term="database" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/database/default.aspx" /><category term="SQL Server" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/SQL+Server/default.aspx" /></entry><entry><title>SQL Server 2000/2005/2008 UDF to return a csv list of values from a query</title><link rel="alternate" type="text/html" href="/blogs/dacrowlah/archive/2009/06/11/sql-server-2000-2005-2008-udf-to-return-a-csv-list-of-values-from-a-query.aspx" /><id>/blogs/dacrowlah/archive/2009/06/11/sql-server-2000-2005-2008-udf-to-return-a-csv-list-of-values-from-a-query.aspx</id><published>2009-06-11T18:22:00Z</published><updated>2009-06-11T18:22:00Z</updated><content type="html">&lt;p&gt;Today I had to do a common task that I&amp;#39;ve done several times, but suddenly realized I should put up here, because its a fairly common issue.&amp;nbsp; Say you have TableA has a one to many relationship to TableB, and you want all of the values in TableB.dbo.ColumnA to be in a csv list based on the FK.&amp;nbsp; This is the perfect place for a simple UDF!&lt;/p&gt;
&lt;p&gt;
&lt;span class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;create&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &lt;span style="color:blue;"&gt;function&lt;/span&gt; [dbo]&lt;span style="color:gray;"&gt;.&lt;/span&gt;[udf_ocrd_getProgList]&lt;span style="color:gray;"&gt;(&lt;/span&gt;@siteid &lt;span style="color:blue;"&gt;nvarchar&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;17&lt;span style="color:gray;"&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;returns&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &lt;span style="color:blue;"&gt;varchar&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:fuchsia;"&gt;max&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;with&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &lt;span style="color:blue;"&gt;execute&lt;/span&gt; &lt;span style="color:blue;"&gt;as&lt;/span&gt; &lt;span style="color:blue;"&gt;caller&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;as&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;begin&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;DECLARE&lt;/span&gt; @ProgTypes &lt;span style="color:blue;"&gt;nvarchar&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:fuchsia;"&gt;max&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;SELECT&lt;/span&gt; @ProgTypes &lt;span style="color:gray;"&gt;=&lt;/span&gt; &lt;span style="color:fuchsia;"&gt;COALESCE&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;@ProgTypes &lt;span style="color:gray;"&gt;+&lt;/span&gt; &lt;span style="color:red;"&gt;&amp;#39;, &amp;#39;&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt; &lt;span style="color:red;"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt; &lt;span style="color:gray;"&gt;+&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &lt;span style="color:fuchsia;"&gt;CAST&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;np&lt;span style="color:gray;"&gt;.&lt;/span&gt;progname &lt;span style="color:blue;"&gt;AS&lt;/span&gt; &lt;span style="color:blue;"&gt;nvarchar&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;65&lt;span style="color:gray;"&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;from&lt;/span&gt; ocrd&lt;span style="color:gray;"&gt;.&lt;/span&gt;progsite ps&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span style="color:gray;"&gt;inner&lt;/span&gt; &lt;span style="color:gray;"&gt;join&lt;/span&gt; ocrd&lt;span style="color:gray;"&gt;.&lt;/span&gt;nprograms np &lt;span style="color:blue;"&gt;on&lt;/span&gt; ps&lt;span style="color:gray;"&gt;.&lt;/span&gt;programid &lt;span style="color:gray;"&gt;=&lt;/span&gt; np&lt;span style="color:gray;"&gt;.&lt;/span&gt;programid&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span style="color:gray;"&gt;inner&lt;/span&gt; &lt;span style="color:gray;"&gt;join&lt;/span&gt; ocrd&lt;span style="color:gray;"&gt;.&lt;/span&gt;sites sites &lt;span style="color:blue;"&gt;on&lt;/span&gt; sites&lt;span style="color:gray;"&gt;.&lt;/span&gt;siteid &lt;span style="color:gray;"&gt;=&lt;/span&gt; ps&lt;span style="color:gray;"&gt;.&lt;/span&gt;siteidlnk&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span style="color:blue;"&gt;where&lt;/span&gt; ps&lt;span style="color:gray;"&gt;.&lt;/span&gt;siteidlnk &lt;span style="color:gray;"&gt;=&lt;/span&gt; @siteid&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;return &lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;@ProgTypes&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;and then to execute it...&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span style="color:red;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
&lt;span class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;select&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; sitename&lt;span style="color:gray;"&gt;,&lt;/span&gt; dbo&lt;span style="color:gray;"&gt;.&lt;/span&gt;udf_getProgList&lt;span style="color:gray;"&gt;(&lt;/span&gt;siteid&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp; &lt;span style="color:blue;"&gt;from&lt;/span&gt; ocrd&lt;span style="color:gray;"&gt;.&lt;/span&gt;sites&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&lt;span style="color:blue;"&gt;where&lt;/span&gt; siteid &lt;span style="color:gray;"&gt;=&lt;/span&gt; &lt;span style="color:red;"&gt;&amp;#39;20030626152018383&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;And it will return &amp;quot;Site Name Here&amp;quot;, &amp;quot;Value 1, Value 2, Value 3&amp;quot;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://strangenut.com/aggbug.aspx?PostID=49" width="1" height="1"&gt;</content><author><name>dacrowlah</name><uri>http://strangenut.com/members/dacrowlah/default.aspx</uri></author><category term="T-SQL" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/T-SQL/default.aspx" /><category term="database" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/database/default.aspx" /><category term="SQL Server" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/SQL+Server/default.aspx" /><category term="Indexes" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/Indexes/default.aspx" /><category term="tips and tricks" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/tips+and+tricks/default.aspx" /></entry><entry><title>How to find all tables with a column of a particular name in SQL Server 2005 and 2008</title><link rel="alternate" type="text/html" href="/blogs/dacrowlah/archive/2009/02/13/how-to-find-all-tables-with-a-column-of-a-particular-name-in-sql-server-2005-and-2008.aspx" /><id>/blogs/dacrowlah/archive/2009/02/13/how-to-find-all-tables-with-a-column-of-a-particular-name-in-sql-server-2005-and-2008.aspx</id><published>2009-02-13T07:37:00Z</published><updated>2009-02-13T07:37:00Z</updated><content type="html">&lt;p&gt;This is a simple query for finding all instances of a column with a particular name along with the table that it belongs to.&amp;nbsp; This will not work on SQL Server 2000.&lt;/p&gt;
&lt;p&gt;&lt;span style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;select&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &lt;span style="color:green;"&gt;sys.objects&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:blue;"&gt;name&lt;/span&gt; &lt;span style="color:blue;"&gt;as&lt;/span&gt; TableName&lt;span style="color:gray;"&gt;,&lt;/span&gt; &lt;span style="color:green;"&gt;sys.columns&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:blue;"&gt;name&lt;/span&gt; &lt;span style="color:blue;"&gt;as&lt;/span&gt; ColumnName&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span style="color:blue;"&gt;from&lt;/span&gt; &lt;span style="color:green;"&gt;sys.columns&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&lt;span style="color:gray;"&gt;inner&lt;/span&gt; &lt;span style="color:gray;"&gt;join&lt;/span&gt; &lt;span style="color:green;"&gt;sys.objects&lt;/span&gt; &lt;span style="color:blue;"&gt;on&lt;/span&gt; &lt;span style="color:green;"&gt;sys.objects&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:fuchsia;"&gt;object_id&lt;/span&gt; &lt;span style="color:gray;"&gt;=&lt;/span&gt; &lt;span style="color:green;"&gt;sys.columns&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:fuchsia;"&gt;object_id&lt;/span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&lt;span style="color:blue;"&gt;where&lt;/span&gt; &lt;span style="color:green;"&gt;sys.columns&lt;/span&gt;&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:blue;"&gt;name&lt;/span&gt; &lt;span style="color:gray;"&gt;=&lt;/span&gt; &lt;span style="color:red;"&gt;&amp;#39;countyid&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://strangenut.com/aggbug.aspx?PostID=47" width="1" height="1"&gt;</content><author><name>dacrowlah</name><uri>http://strangenut.com/members/dacrowlah/default.aspx</uri></author><category term="T-SQL" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/T-SQL/default.aspx" /><category term="database" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/database/default.aspx" /><category term="SQL Server" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/SQL+Server/default.aspx" /><category term="beginner" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/beginner/default.aspx" /><category term="tips and tricks" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/tips+and+tricks/default.aspx" /></entry><entry><title>How to use the row_number function in SQL Server 2005 and 2008 for server side data paging in T-SQL</title><link rel="alternate" type="text/html" href="/blogs/dacrowlah/archive/2009/01/29/how-to-use-the-row-number-function-in-sql-server-2005-and-2008-for-server-side-data-paging-in-t-sql.aspx" /><id>/blogs/dacrowlah/archive/2009/01/29/how-to-use-the-row-number-function-in-sql-server-2005-and-2008-for-server-side-data-paging-in-t-sql.aspx</id><published>2009-01-29T18:59:00Z</published><updated>2009-01-29T18:59:00Z</updated><content type="html">&lt;p&gt;This technique is fairly handy for server side data paging, it essentially executes the statement server side, then grabs a subsection of the rows (that you specify) and only returns those to the client.&amp;nbsp; This will reduce network traffic pretty considerably, and subsequently speed up your applications response times if network chatter is a problem.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:10pt;font-family:Courier New;color:blue;"&gt;with&lt;/span&gt;&lt;span style="font-size:10pt;font-family:Courier New;"&gt; employeeDataSlice &lt;span style="color:blue;"&gt;as&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
    &lt;span style="font-size:10pt;font-family:Courier New;color:gray;"&gt;(&lt;/span&gt;&lt;br /&gt;
    &lt;span style="font-size:10pt;font-family:Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;select&lt;/span&gt; &lt;span style="color:gray;"&gt;*,&lt;/span&gt; row_number&lt;span style="color:gray;"&gt;()&lt;/span&gt; &lt;span style="color:blue;"&gt;over&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;order&lt;/span&gt; &lt;span style="color:blue;"&gt;by&lt;/span&gt; EmployeeID &lt;span style="color:blue;"&gt;asc&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt; &lt;span style="color:blue;"&gt;as&lt;/span&gt; displayRowNum &lt;/span&gt;&lt;br /&gt;
    &lt;span style="font-size:10pt;font-family:Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt; from&lt;/span&gt; [HumanResources]&lt;span style="color:gray;"&gt;.&lt;/span&gt;[Employee]&lt;/span&gt;&lt;br /&gt;
  &lt;span style="font-size:10pt;font-family:Courier New;color:gray;"&gt;)&lt;/span&gt;&lt;br /&gt;
  &lt;span style="font-size:10pt;font-family:Courier New;color:blue;"&gt;select&lt;/span&gt;&lt;span style="font-size:10pt;font-family:Courier New;"&gt; &lt;span style="color:gray;"&gt;*&lt;/span&gt; &lt;span style="color:blue;"&gt;from&lt;/span&gt; employeeDataSlice &lt;span style="color:blue;"&gt;where&lt;/span&gt; displayRowNum &lt;span style="color:gray;"&gt;between&lt;/span&gt; 1 &lt;span style="color:gray;"&gt;and&lt;/span&gt; 5&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://strangenut.com/aggbug.aspx?PostID=46" width="1" height="1"&gt;</content><author><name>dacrowlah</name><uri>http://strangenut.com/members/dacrowlah/default.aspx</uri></author><category term="T-SQL" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/T-SQL/default.aspx" /><category term="database" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/database/default.aspx" /><category term="SQL Server" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/SQL+Server/default.aspx" /><category term="tips and tricks" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/tips+and+tricks/default.aspx" /></entry><entry><title>How to create a table with a non clustered primary key in SQL Server 2000 2005 and 2008</title><link rel="alternate" type="text/html" href="/blogs/dacrowlah/archive/2009/01/24/how-to-create-a-table-with-a-non-clustered-primary-key-in-sql-server-2000-2005-and-2008.aspx" /><id>/blogs/dacrowlah/archive/2009/01/24/how-to-create-a-table-with-a-non-clustered-primary-key-in-sql-server-2000-2005-and-2008.aspx</id><published>2009-01-24T20:54:00Z</published><updated>2009-01-24T20:54:00Z</updated><content type="html">&lt;p&gt;Unless otherwise specified when you create your tables primary key in SQL Server 2000, 2005 and 2008 will have a clustered index on it.&amp;nbsp; This will be a good default choice if you are going to be joining other tables together on this value.&amp;nbsp; If you are going to be joining or selecting based on another value in the table, then you should probably use a nonclustered primary key.&amp;nbsp; Here is how you do it in T-SQL at the time of table creation:&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;create&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &lt;span style="color:blue;"&gt;table&lt;/span&gt; &lt;span style="color:black;"&gt;DemonstrationTable&lt;/span&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:gray;"&gt;(&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:black;"&gt;TableIdColumn&lt;/span&gt; &lt;span style="color:blue;"&gt;int&lt;/span&gt; &lt;span style="color:blue;"&gt;identity&lt;/span&gt; &lt;span style="color:gray;"&gt;not&lt;/span&gt; &lt;span style="color:gray;"&gt;null&lt;/span&gt; &lt;span style="color:blue;"&gt;primary&lt;/span&gt; &lt;span style="color:blue;"&gt;key&lt;/span&gt; &lt;span style="color:blue;"&gt;nonclustered&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:black;"&gt;TableValueColumn&lt;/span&gt; &lt;span style="color:blue;"&gt;nvarchar&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;255&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:gray;"&gt;)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;go&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://strangenut.com/aggbug.aspx?PostID=45" width="1" height="1"&gt;</content><author><name>dacrowlah</name><uri>http://strangenut.com/members/dacrowlah/default.aspx</uri></author><category term="T-SQL" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/T-SQL/default.aspx" /><category term="database" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/database/default.aspx" /><category term="SQL Server" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/SQL+Server/default.aspx" /><category term="Indexes" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/Indexes/default.aspx" /></entry><entry><title>Changing a clustered primary key to non-clustered in SQL Server 2000/2005/2008</title><link rel="alternate" type="text/html" href="/blogs/dacrowlah/archive/2009/01/18/changing-a-clustered-primary-key-to-non-clustered-in-sql-server-2000-2005-2008.aspx" /><id>/blogs/dacrowlah/archive/2009/01/18/changing-a-clustered-primary-key-to-non-clustered-in-sql-server-2000-2005-2008.aspx</id><published>2009-01-19T03:25:00Z</published><updated>2009-01-19T03:25:00Z</updated><content type="html">&lt;p&gt;By default, when you create a primary key column in SQL Server, it makes it a clustered index.&amp;nbsp; Sometimes this will be a default advantage, sometimes a serious disadvantage for performance as clustered indexes are the cornerstone of performance tuning in SQL Server.&amp;nbsp; In the event that a clustered primary key gets created and you need to change it to a non-clustered one, follow these steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the table in design view in SQL Server Management Studio (right click on the table in the object explorer, click &amp;#39;Modify&amp;#39;)&lt;/li&gt;
&lt;li&gt;Right Click anywhere over the column definitions, from the context menu click &amp;#39;Indexes/Keys&amp;#39;&lt;/li&gt;
&lt;li&gt;Select your primary keys index by name in the right listbox&lt;/li&gt;
&lt;li&gt;In the right pane, under the section titled &amp;#39;Table Designer&amp;#39; find the item labeled &amp;#39;Create as Clustered&amp;#39; and change the &amp;#39;Yes&amp;#39; to &amp;#39;No&amp;#39;.&lt;/li&gt;
&lt;li&gt;Click close, then close the design view of the table, and choose the option to save.&lt;/li&gt;
&lt;li&gt;If you have full text catalogs on this table you may need to repopulate them.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That should be it, now you are able to create a clustered index on another column or set of columns on your table.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://strangenut.com/aggbug.aspx?PostID=44" width="1" height="1"&gt;</content><author><name>dacrowlah</name><uri>http://strangenut.com/members/dacrowlah/default.aspx</uri></author><category term="T-SQL" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/T-SQL/default.aspx" /><category term="performance tuning" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/performance+tuning/default.aspx" /><category term="database" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/database/default.aspx" /><category term="SQL Server" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/SQL+Server/default.aspx" /><category term="Indexes" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/Indexes/default.aspx" /></entry><entry><title>What does schemabinding mean in SQL 2005 and 2008?</title><link rel="alternate" type="text/html" href="/blogs/dacrowlah/archive/2008/12/02/what-does-schemabinding-mean-in-sql-2005-and-2008.aspx" /><id>/blogs/dacrowlah/archive/2008/12/02/what-does-schemabinding-mean-in-sql-2005-and-2008.aspx</id><published>2008-12-02T16:06:00Z</published><updated>2008-12-02T16:06:00Z</updated><content type="html">&lt;p&gt;In order for us to be able to create an indexed view, we need to create that view with SCHEMABINDING specified. What exactly does SCHEMABINDING mean?&amp;nbsp; Here is the definition from MSDN:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SCHEMABINDING&lt;/strong&gt; &lt;br /&gt;Binds the view to the schema of the underlying table or tables. When SCHEMABINDING is specified, the base table or tables cannot be modified in a way that would affect the view definition. The view definition itself must first be modified or dropped to remove dependencies on the table that is to be modified. When you use SCHEMABINDING, the select_statement must include the two-part names (schema.object) of tables, views, or user-defined functions that are referenced. All referenced objects must be in the same database.&lt;/p&gt;
&lt;p&gt;Views or tables that participate in a view created with the SCHEMABINDING clause cannot be dropped unless that view is dropped or changed so that it no longer has schema binding. Otherwise, the Microsoft SQL Server 2005 Database Engine raises an error. Also, executing ALTER TABLE statements on tables that participate in views that have schema binding fail when these statements affect the view definition.&lt;/p&gt;
&lt;p&gt;SCHEMABINDING cannot be specified if the view contains alias data type columns.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What does this mean?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Well, to put it simply, once you create a view with schemabinding, you cannot change the underlying tables in a way that would break the view.&amp;nbsp; Examples of this would be removing columns or dropping tables that are specified in the view.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://strangenut.com/aggbug.aspx?PostID=40" width="1" height="1"&gt;</content><author><name>dacrowlah</name><uri>http://strangenut.com/members/dacrowlah/default.aspx</uri></author><category term="T-SQL" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/T-SQL/default.aspx" /><category term="database" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/database/default.aspx" /><category term="SQL Server" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/SQL+Server/default.aspx" /></entry><entry><title>Creating an Indexed View in SQL Server 2005 and 2008</title><link rel="alternate" type="text/html" href="/blogs/dacrowlah/archive/2008/11/26/creating-an-indexed-view-in-sql-server-2005-and-2008.aspx" /><id>/blogs/dacrowlah/archive/2008/11/26/creating-an-indexed-view-in-sql-server-2005-and-2008.aspx</id><published>2008-11-26T22:33:00Z</published><updated>2008-11-26T22:33:00Z</updated><content type="html">&lt;p&gt;As you probably are already aware, a view in SQL Server is generated off of a pre-defined select statement, and is a flexible solution to use when ever you are doing database driven application development; particularly when you are using an ORM tool (like SubSonic or EntitySpaces as examples).&amp;nbsp; However, for performance reasons there is an additional piece you should be aware of and this is what is known as an &amp;quot;indexed view&amp;quot;.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;On the surface, an indexed view is the same thing as a normal view, however the critical difference is that an indexed view actually allows you to create a clustered index on it, effectively working around the &amp;quot;one clustered index per table&amp;quot; limitation. The downside to this is that the indexed view is a full copy of the data from the underlying tables, so for space considerations you will need to take this into account when using them.&lt;/p&gt;
&lt;p&gt;Let&amp;#39;s look first at how to create a normal view, so that we have something to compare to as we create an indexed view&lt;/p&gt;
&lt;p&gt;

&lt;br class="MsoNormal" /&gt;&lt;span style="font-size:10pt;color:#0000ff;font-family:&amp;#39;Courier New&amp;#39;;"&gt;create&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &lt;span style="color:#0000ff;"&gt;view&lt;/span&gt; ContactsView &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; &lt;/span&gt;&lt;br class="MsoNormal" /&gt;&lt;span style="font-size:10pt;color:#808080;font-family:&amp;#39;Courier New&amp;#39;;"&gt;(&lt;/span&gt; &lt;br class="MsoNormal" /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;select&lt;/span&gt; [Users]&lt;span style="color:#808080;"&gt;.&lt;/span&gt;[FirstName]&lt;span style="color:#808080;"&gt;,&lt;/span&gt; [Users]&lt;span style="color:#808080;"&gt;.&lt;/span&gt;[LastName]&lt;span style="color:#808080;"&gt;,&lt;/span&gt; [Contacts]&lt;span style="color:#808080;"&gt;.*&lt;/span&gt;&lt;/span&gt; &lt;br class="MsoNormal" /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span style="color:#0000ff;"&gt;from&lt;/span&gt; [Users]&lt;/span&gt; &lt;br class="MsoNormal" /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span style="color:#808080;"&gt;inner&lt;/span&gt; &lt;span style="color:#808080;"&gt;join&lt;/span&gt; [Contacts] &lt;span style="color:#0000ff;"&gt;on&lt;/span&gt; [Contacts]&lt;span style="color:#808080;"&gt;.&lt;/span&gt;[UserID] &lt;span style="color:#808080;"&gt;=&lt;/span&gt; [Users]&lt;span style="color:#808080;"&gt;.&lt;/span&gt;[UserId]&lt;/span&gt; &lt;br class="MsoNormal" /&gt;&lt;span style="font-size:10pt;color:#808080;font-family:&amp;#39;Courier New&amp;#39;;"&gt;);&lt;/span&gt;&lt;span style="font-size:11pt;font-family:Calibri;"&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;What this will do is create a pretty flexible view that will only pull the first and last name of the user from the users table, and all of the columns from the Contacts table and automatically pick up any new columns that are added to the Contacts table, with no further modifications.&amp;nbsp; Indexed views require a more rigid definition of what they will return.&amp;nbsp; For this reason, we cannot use a wildcard (*) in the underlying query.&amp;nbsp; Each column must be individually called out; also,&amp;nbsp;each table named in the query must be in 2 part dot notation, referencing both the schema of the table and the table name itself, and the view must be declared with &lt;a target="_self" href="http://strangenut.com/blogs/dacrowlah/archive/2008/12/02/what-does-schemabinding-mean-in-sql-2005-and-2008.aspx" title="Definition of schemabinding"&gt;schemabinding&lt;/a&gt; enabled for it.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Below is the modified query to create a view capable of being an indexed view:&lt;/p&gt;
&lt;p&gt;

&lt;br class="MsoNormal" /&gt;&lt;span style="font-size:10pt;color:#0000ff;font-family:&amp;#39;Courier New&amp;#39;;"&gt;create&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &lt;span style="color:#0000ff;"&gt;view&lt;/span&gt; [dbo]&lt;span style="color:#808080;"&gt;.&lt;/span&gt;[OrganizationContactsView] &lt;span style="color:#0000ff;"&gt;with&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;schemabinding&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt;&lt;/span&gt; &lt;br class="MsoNormal" /&gt;&lt;span style="font-size:10pt;color:#808080;font-family:&amp;#39;Courier New&amp;#39;;"&gt;(&lt;/span&gt; &lt;br class="MsoNormal" /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;select&lt;/span&gt; [FirstName]&lt;span style="color:#808080;"&gt;,&lt;/span&gt; [LastName]&lt;span style="color:#808080;"&gt;,&lt;/span&gt; [Contacts]&lt;span style="color:#808080;"&gt;.&lt;/span&gt;[UserID]&lt;span style="color:#808080;"&gt;,&lt;/span&gt; [Contacts]&lt;span style="color:#808080;"&gt;.&lt;/span&gt;[ContactDescription]&lt;span style="color:#808080;"&gt;,&lt;/span&gt; [Contacts]&lt;span style="color:#808080;"&gt;.&lt;/span&gt;[IsPublic]&lt;/span&gt; &lt;br class="MsoNormal" /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span style="color:#0000ff;"&gt;from&lt;/span&gt; [dbo]&lt;span style="color:#808080;"&gt;.&lt;/span&gt;[Contacts]&lt;/span&gt; &lt;br class="MsoNormal" /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span style="color:#808080;"&gt;inner&lt;/span&gt; &lt;span style="color:#808080;"&gt;join&lt;/span&gt; [dbo]&lt;span style="color:#808080;"&gt;.&lt;/span&gt;[Users] &lt;span style="color:#0000ff;"&gt;on&lt;/span&gt; [Contacts]&lt;span style="color:#808080;"&gt;.&lt;/span&gt;[UserID] &lt;span style="color:#808080;"&gt;=&lt;/span&gt; [Users]&lt;span style="color:#808080;"&gt;.&lt;/span&gt;[UserId] &lt;/span&gt;&lt;br class="MsoNormal" /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&lt;span style="color:#808080;"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:11pt;font-family:Calibri;"&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Now, we need to create the clustered index on it.&amp;nbsp; Clustered indexes on a view must be unique, otherwise you will not be able to create one; nonclustered indexes will work fine.&amp;nbsp; For the present example, a UserId will only be in the contacts table once per Organization, so we can make a unique clustered index spanning the OrgId and UserId columns, like this:&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:#0000ff;font-family:&amp;#39;Courier New&amp;#39;;"&gt;create&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &lt;span style="color:#0000ff;"&gt;unique&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;clustered&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;index&lt;/span&gt; IX_OrganizationContactsView_OrgId &lt;span style="color:#0000ff;"&gt;on&lt;/span&gt; [OrganizationContactsView]&lt;span style="color:#808080;"&gt;(&lt;/span&gt;OrgId&lt;span style="color:#808080;"&gt;,&lt;/span&gt;UserId&lt;span style="color:#808080;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:11pt;font-family:Calibri;"&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;And, there we are, a clustered index!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://strangenut.com/aggbug.aspx?PostID=39" width="1" height="1"&gt;</content><author><name>dacrowlah</name><uri>http://strangenut.com/members/dacrowlah/default.aspx</uri></author><category term="T-SQL" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/T-SQL/default.aspx" /><category term="performance tuning" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/performance+tuning/default.aspx" /><category term="database" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/database/default.aspx" /><category term="SQL Server" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/SQL+Server/default.aspx" /></entry><entry><title>Writing Your First CLR Stored Procedure</title><link rel="alternate" type="text/html" href="/blogs/dacrowlah/archive/2008/10/31/writing-your-first-clr-stored-procedure.aspx" /><link rel="enclosure" type="text/plain" length="1021" href="http://strangenut.com/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.00.00.35/Sales_2E00_cs" /><id>/blogs/dacrowlah/archive/2008/10/31/writing-your-first-clr-stored-procedure.aspx</id><published>2008-10-31T23:25:00Z</published><updated>2008-10-31T23:25:00Z</updated><content type="html">&lt;p&gt;In SQL Server 2005 and 2008 the Common Language Runtmie (CLR) is tightly integrated with the database engine, allowing you to write stored procedures in any .NET language such as C# and VB.NET.&amp;nbsp; CLR stored procedures have some distinct advantages over traditional stored procedures, and they also have their drawbacks. In the world of application developers who use languages like C# and the world of database developers who use T-SQL, there are different definitions of &amp;quot;maintainability&amp;quot;, and ultimately it will come down to what camp most of your development staff are in.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;If you have a comfort level or more staff for database maintenance, then traditional stored procedures will fit into your architecture more easily, and CLR stored procedures will augment where specifically needed.&amp;nbsp; However, when used properly CLR stored procedures will be a powerful tool in your development arsenal.&amp;nbsp; The drawbacks to them are that they are deployed very differently (i.e. you can&amp;#39;t run a create script in Management Studio and be done with it; you need to either deploy the assembly through Visual Studio to a database, or physically copy the assembly to the database server, and then register it manually in Management Studio, also you do lose some tracing data that you would normally see inside of SQL Profiler.&amp;nbsp; Some of the more appropriate times to use them however are during operations that require high speed text manipulation, cryptography, and remotely accessing resources outside of SQL Server (such as calling a webservice to geocode address data).&lt;/p&gt;
&lt;p&gt;Before we begin with creating our first CLR Stored Procedure, we need to enable the CLR in the database that we want to deploy the procedure to; to do this you can reference my previous posting on &lt;a target="_blank" title="How To Enable CLR Stored Procedures" href="http://strangenut.com/blogs/dacrowlah/archive/2008/10/26/how-to-enable-clr-stored-procedures-on-sql-server-2005-and-2008.aspx"&gt;How to Enable CLR Stored Procedures&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Step One: Createing the CLR Procedure Project&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;To create the initial project, click on File -&amp;gt; New-&amp;gt; Project; then select Visual C#-&amp;gt; Database-&amp;gt; SQL Server Project&lt;/p&gt;
&lt;p&gt;&lt;img alt="Creation of the Visual Studio Project for CLR Stored Procedure" src="http://strangenut.com/cfs-filesystemfile.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/dacrowlah/clr_2D00_stored_2D00_procedure_2D00_create_2D00_project.gif" width="683" height="490" /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Let&amp;#39;s name the project CLRStoredProcedures, and click ok.&amp;nbsp; During the project creation phase, you will be prompted to add a reference to a database for the current project, create one to the AdventureWorks database if you don&amp;#39;t already have one, and select that.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Step Two: Add a Stored Procedure to the Project&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Next we need to add stored procedure class to the project, where we can add our methods.&amp;nbsp; To do this, right click in the Solution Explorer, select &amp;quot;Add&amp;quot;, and then select &amp;quot;Stored Procedure...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;img alt="Adding a stored procedure to the CLR project" src="http://strangenut.com/cfs-filesystemfile.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/dacrowlah/clr-stored-procedures-add-stored-procedure-to-project.gif" width="683" height="414" /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;After the item is added to the project you will be looking at a blank stub method in a C# class file, where you can customize the code to do what you need.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img alt="blank clr stored procedure stub" src="http://strangenut.com/cfs-filesystemfile.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/dacrowlah/clr-stored-procedures-blank-code-file.gif" width="549" height="452" /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now, let&amp;#39;s go ahead and change the code in this file, so we can do something productive with it!&lt;/p&gt;
&lt;p&gt;First, we should change the method name to something useful, in this case we can use the name &amp;quot;GetCustomersByTerritoryID&amp;quot;.&amp;nbsp; Guessing based on the name, we will need to be passing in an argument, TerritoryID to our procedure, so also add an argument to the function called &amp;quot;TerritoryID&amp;quot; and of type int.&amp;nbsp; Below, is the code for the procedure, you can copy and paste it, and I will explain line by line what is going on.&lt;/p&gt;
&lt;p&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Microsoft.SqlServer.Server.&lt;span style="color:#2b91af;"&gt;SqlProcedure&lt;/span&gt;]&lt;/span&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; GetCustomersByTerritoryID(&lt;span style="color:blue;"&gt;int&lt;/span&gt; TerritoryId)&lt;/span&gt;
&lt;p&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span style="color:#2b91af;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span style="color:#2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SqlPipe&lt;/span&gt; pipe = &lt;span style="color:#2b91af;"&gt;SqlContext&lt;/span&gt;.Pipe;&lt;/span&gt;&lt;/p&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;SqlCommand&lt;/span&gt; cmd = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;SqlCommand&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;select * from [Sales].[Customer] where  [TerritoryID] = @TerritoryID&amp;quot;&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cmd.Parameters.AddWithValue(&lt;span style="color:#a31515;"&gt;&amp;quot;@TerritoryID&amp;quot;&lt;/span&gt;, TerritoryId);&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;using&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;SqlConnection&lt;/span&gt; con = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;SqlConnection&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;context  connection=true&amp;quot;&lt;/span&gt;))&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;try&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cmd.Connection = con;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; con.Open();&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pipe.ExecuteAndSend(cmd);&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;catch&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;Exception&lt;/span&gt; ex)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;throw&lt;/span&gt; ex;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;finally&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue;"&gt;if&lt;/span&gt; (con != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; con.Close();&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Ok, once we get inside the declaration of the procedure, the first line is &lt;span class="MsoNormal" style="text-autospace:none;"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span style="color:#2b91af;"&gt;SqlPipe&lt;/span&gt; pipe = &lt;span style="color:#2b91af;"&gt;SqlContext&lt;/span&gt;.Pipe;&lt;/span&gt;&lt;/span&gt; this is the mechanism that we have available to us to send any results back to the client.&amp;nbsp; I am going to make some basic assumptions that you have experience working with ASP.NET or data access with C#, and can already see the similarities here.&amp;nbsp; We start off with instantiating a SqlCommand object, giving it a query to execute that is properly parameterized, and opening a database connection.&amp;nbsp; Now, notice here that it does have a very different connection string that we are used to. It does not specify a server, database, username or password... or for that matter anything we normally see in a connection string.&amp;nbsp; That is because we are already connected to the database and are already authenticated, so none of that is necessary.&amp;nbsp; We simply set the &amp;quot;Context Connection=true&amp;quot; flag, and we&amp;#39;re set!&lt;/p&gt;
&lt;p&gt;The next big difference you see is that we are calling the ExecuteAndSend() function on the pipe object, and passing in the SqlCommand object as an argument; doing this executes the command and sends any subsequent results back to the caller.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Step Three: Build, Deploy, and Execute!&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Now that we have the code already laid down, the final step is upon us, we first build the class file by clicking &amp;quot;Build&amp;quot; on the top menu, then choose the option to build it, then &amp;quot;Build&amp;quot; again, and choose deploy.&amp;nbsp; After this says &amp;quot;Deploy Successful&amp;quot; in the status pane, we jump over into Management Studio, open up a query window to the AdventureWorks database, and try executing it&lt;/p&gt;
&lt;p&gt;&lt;img alt="executing the final built and deployed clr stored procedure" src="http://strangenut.com/cfs-filesystemfile.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/dacrowlah/clr-stored-procedures-execute-built-procedure.gif" width="760" height="359" /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;And that&amp;#39;s it! We are done with our first CLR Stored procedure, you can call this like you normally would any stored procedure, and better yet, you can take advantage of the .NET framework from inside of SQL Server 2005 and 2008 from languages and platforms other than ASP.NET!&amp;nbsp; ColdFusion, Classic ASP, PHP, all of them can benefit from this integration with no requirements on the application side!&amp;nbsp; Attached to this post is the actual C# class file used in this tutorial.&lt;/p&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://strangenut.com/aggbug.aspx?PostID=35" width="1" height="1"&gt;</content><author><name>dacrowlah</name><uri>http://strangenut.com/members/dacrowlah/default.aspx</uri></author><category term="T-SQL" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/T-SQL/default.aspx" /><category term="database" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/database/default.aspx" /><category term="SQL Server" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/SQL+Server/default.aspx" /><category term="c#" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/c_2300_/default.aspx" /><category term="stored procedure" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/stored+procedure/default.aspx" /><category term="CLR Stored Procedures" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/CLR+Stored+Procedures/default.aspx" /></entry><entry><title>How to enable CLR Stored procedures on SQL Server 2005 and 2008</title><link rel="alternate" type="text/html" href="/blogs/dacrowlah/archive/2008/10/26/how-to-enable-clr-stored-procedures-on-sql-server-2005-and-2008.aspx" /><id>/blogs/dacrowlah/archive/2008/10/26/how-to-enable-clr-stored-procedures-on-sql-server-2005-and-2008.aspx</id><published>2008-10-27T01:53:00Z</published><updated>2008-10-27T01:53:00Z</updated><content type="html">&lt;p&gt;In order to make CLR stored procedures run, you must first enable the CLR in SQL Server, other wise you will just get this error:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Execution of user code in the .NET Framework is disabled. Enable &amp;quot;clr enabled&amp;quot; configuration option.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Enabling the CLR is fairly simple, just run this SQL Statement in Query Analyzer, while connected to the database that needs this option enabled:&lt;/p&gt;
&lt;pre&gt;&lt;p&gt;EXEC sp_configure &amp;#39;show advanced options&amp;#39; , &amp;#39;1&amp;#39;; &lt;br /&gt;reconfigure; &lt;br /&gt;&lt;br /&gt;EXEC sp_configure &amp;#39;clr enabled&amp;#39; , &amp;#39;1&amp;#39; ;&lt;br /&gt;reconfigure; &lt;br /&gt;&lt;br /&gt;EXEC sp_configure &amp;#39;show advanced options&amp;#39; , &amp;#39;0&amp;#39;; &lt;br /&gt;reconfigure;&lt;/p&gt;&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://strangenut.com/aggbug.aspx?PostID=34" width="1" height="1"&gt;</content><author><name>dacrowlah</name><uri>http://strangenut.com/members/dacrowlah/default.aspx</uri></author><category term="T-SQL" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/T-SQL/default.aspx" /><category term="database" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/database/default.aspx" /><category term="SQL Server" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/SQL+Server/default.aspx" /><category term="beginner" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/beginner/default.aspx" /><category term="stored procedure" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/stored+procedure/default.aspx" /></entry><entry><title>Making the case for stored procedures</title><link rel="alternate" type="text/html" href="/blogs/dacrowlah/archive/2008/10/26/making-the-case-for-stored-procedures.aspx" /><id>/blogs/dacrowlah/archive/2008/10/26/making-the-case-for-stored-procedures.aspx</id><published>2008-10-26T07:23:00Z</published><updated>2008-10-26T07:23:00Z</updated><content type="html">&lt;p&gt;On a few of the mailing lists I am on for developers (primarily ones related to web development), there is a recurring topic that always gets people into rather heated debates: to use stored procedures or prepared statements?&amp;nbsp; Now, either one you choose to use, is largely dependent on two things: preference/comfort level, and the appropriate tool for the appropriate job.&amp;nbsp; This will be my attempt at defining (my opinion of) the right tool for the right job, while allowing for maximum flexibility.&lt;br /&gt;&lt;br /&gt;Now, for those who are not aware of the difference, a prepared statement is straight SQL sent to the db for execution, but with explicitly declared parameters so as to prevent SQL injection attacks. The techniques on how to do this vary from language to language, but in ColdFusion it is through the use of the &amp;lt;cfqueryparam&amp;gt; tag, and in .NET, you use the SqlCommand object, type of text, and where you want the parameter values, you place a &amp;ldquo;?&amp;rdquo;, then add the parameters in the proper order.&lt;br /&gt;&lt;br /&gt;Now, prepared statements are not a bad thing at all; they offer some of the same benefits of stored procedures: explicit parameterization, elevated chances of execution plan reuse, saves overhead on the db side of having to do type checking/conversion, etc.&amp;nbsp; One additional benefit of using prepared statements, it&amp;rsquo;s a heck of a lot easier to write secure dynamic SQL for complex query building.&lt;br /&gt;&lt;br /&gt;However, stored procedures are a far better choice 99% of the time; complex dynamic SQL being the sole exception that I would consent to allowing in any database I was in charge of administering or code being checked in by a developer who worked for me. Stored procedures have several distinct advantages over prepared statements (or inline SQL in general) , and some of them become more apparent only after having built large, complex, enterprise level applications that have multiple developers and support staff working on them.&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Guaranteed execution plan reuse&lt;/li&gt;
&lt;li&gt;As long as you aren&amp;rsquo;t doing dynamic SQL within your stored proc and concatenating strings for execution, absolutely no chance of a SQL injection attack happening&lt;/li&gt;
&lt;li&gt;Performance increases for saving on permissions checks &amp;ndash; when you submit a prepared statement for execution the database server needs to check the permissions chain on every object that that query touches, EVERY time it executes.&amp;nbsp; This is not the same as an execution plan. With a stored procedure you create the procedure and GRANT EXECUTE for that proc to the Id that your web application connects to the database as.&lt;/li&gt;
&lt;li&gt;Carefully controlled access to data &amp;ndash; sometimes your data has sensitive information (like Social Security Numbers, secret question/answer information, etc) and while you have to both store that information, and maintain a level of security around it so that not everyone in the IT department has access to it, you create a stored proc, and enforce access to the data through stored procedures.&amp;nbsp; This method also gives you the ability to give partial access to data (such as a redacted SSN, instead of the full SSN)&lt;/li&gt;
&lt;li&gt;Modularity of code &amp;ndash; complex logic for doing multiple operations to data in the database is easily ported from one process to another.&amp;nbsp; As an example, one application I routinely work on has 3 different methods for creating a user (new user auto-registration, administrative interface for creating them by uploading an excel file, and one that creates them via a scheduled batch job from excel files uploaded by clients) and there is some pretty complex logic for finding duplicate users across multiple clients and preventing new users from being created who exist elsewhere.&amp;nbsp;&amp;nbsp; Since this piece of code is in the stored procedure, adding new sources and tools to create users is dead simple&amp;hellip; call the stored procedure and that is that.&amp;nbsp; One argument that I heard to try and minimize the impact of this advantage &amp;ldquo;what if you had a single, well architected application written in a single language and the query was easily available from other sections of code within the application, why is there a modularity advantage for this?&amp;nbsp; Well, if you have a single language in your application, and its easily accessible everywhere else, it does lower the points this one gives you, but that was kind of my point here, it lends flexibility even if you don&amp;rsquo;t anticipate needing it now.&lt;/li&gt;
&lt;li&gt;Minimizing the amount of traffic sent over the wire.&amp;nbsp; Sometimes as developers we think 10Mbps/100Mbps/1000Mbps Ethernet has so much bandwidth that sending this little tiny 20 line query over the wire has no impact and won&amp;rsquo;t cause any appreciable slowdown.&amp;nbsp; Well, that is true for the most part, but wait till your application starts getting a ton of traffic&amp;hellip; the more packets you send over the wire, the higher your collision rate on the network, and you&amp;rsquo;ll see reduced network efficiency, sad but true; also one of the most often overlooked reasons for using stored procedures. &lt;/li&gt;
&lt;li&gt;Wise choices in location of your business logic will greatly reduce your round trips to the database when using stored procedures.&amp;nbsp; If you are performing an operation that can be completed from a solid set of parameters from start to finish and the end result (success/failure) is the only thing you need to know, a stored procedure is what you need.&amp;nbsp; Since this was just used as an example I&amp;rsquo;ll use it again: say you are creating a user you have first name, last name, email, address, list of positions, departments, and supervisors.&amp;nbsp; If you have ALL of that logic in your middle tier and not in a stored procedure, you will have to keep going back and doing lookups for data, making more round trips to save, add, and then complete.&amp;nbsp; All of these round trips add to network overhead, time spent encoding/decoding data to send across the wire, process... locate, return&amp;hellip;&amp;nbsp; lots of data, lots of network chatter.&amp;nbsp; This would all be eliminated with a stored procedure, you would feed one set of data to the proc, and execute it, and everything will be handled server side and the result handed back to you.&lt;/li&gt;
&lt;li&gt;Centralization of maintenance, changes, security, and stronger separation of tiers. &lt;/li&gt;
&lt;li&gt;Ease in separation in application tiers for troubleshooting.&amp;nbsp; If you write a stored proc, use it in your application, and suddenly start seeing weird results in the application, you can go, execute the proc, and eyeball the results&amp;hellip; do they look weird? No? Then the chances are good the problem lies in your application layer, start looking there.&amp;nbsp; Many years of supporting messy applications and code taught me this lesson all too well.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://strangenut.com/aggbug.aspx?PostID=33" width="1" height="1"&gt;</content><author><name>dacrowlah</name><uri>http://strangenut.com/members/dacrowlah/default.aspx</uri></author><category term="query execution plans" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/query+execution+plans/default.aspx" /><category term="T-SQL" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/T-SQL/default.aspx" /><category term="performance tuning" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/performance+tuning/default.aspx" /><category term="database" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/database/default.aspx" /><category term="SQL Server" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/SQL+Server/default.aspx" /><category term="beginner" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/beginner/default.aspx" /><category term="stored procedure" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/stored+procedure/default.aspx" /></entry><entry><title>Getting a range of values from an arbitrary starting point in T-SQL</title><link rel="alternate" type="text/html" href="/blogs/dacrowlah/archive/2008/08/07/getting-a-range-of-values-from-an-arbitrary-starting-point-in-t-sql.aspx" /><id>/blogs/dacrowlah/archive/2008/08/07/getting-a-range-of-values-from-an-arbitrary-starting-point-in-t-sql.aspx</id><published>2008-08-07T17:40:00Z</published><updated>2008-08-07T17:40:00Z</updated><content type="html">&lt;p&gt;Recently a friend of mine called with a question about how to do something in T-SQL that he wanted to do for the leaderboard for a game he wrote.&amp;nbsp; The issue was that tens of thousands of people are playing his game (on the iPhone)&amp;nbsp; and the screen real estate only allowed for about 10 players scores to be displayed.&amp;nbsp; The present method only displayed the top 10 scores, and did not include the current players score, so they never really saw where people were in relation to them.&lt;/p&gt;
&lt;p&gt;He wanted something a bit more relevant to the player.&amp;nbsp; The solution was to display the closest 9 scores in relation to the player, 4 greater than, and 5 less than.&amp;nbsp; This is the solution I presented to him on a conceptual basis, actual implementation may vary and you would probably want to create an indexed view to run this query against with a clustered index on the column containing the players score and the players UserId, adding other columns as necessary to display the data you want.&amp;nbsp; This example will run as is without creating any tables or making any temp tables (uses only Table type variables).&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style="padding-left:15px;"&gt;
&lt;pre&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;declare&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; @PlayerScores &lt;span style="color:blue;"&gt;table&lt;/span&gt; &lt;span style="color:gray;"&gt;(&lt;/span&gt;ScoreValue &lt;span style="color:blue;"&gt;int&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;declare&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; @TempScores &lt;span style="color:blue;"&gt;table&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;ScoreValue &lt;span style="color:blue;"&gt;int&lt;/span&gt;&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;declare&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; @currentScore &lt;span style="color:blue;"&gt;int&lt;/span&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;&lt;br /&gt;set&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; @currentScore &lt;span style="color:gray;"&gt;=&lt;/span&gt; 0&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;while&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &lt;span style="color:gray;"&gt;(&lt;/span&gt;@currentScore &lt;span style="color:gray;"&gt;&amp;lt;&lt;/span&gt; 101&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;begin&lt;/span&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;set&lt;/span&gt; @currentScore &lt;span style="color:gray;"&gt;=&lt;/span&gt; @currentScore &lt;span style="color:gray;"&gt;+&lt;/span&gt; 1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;insert&lt;/span&gt; &lt;span style="color:blue;"&gt;into&lt;/span&gt; @PlayerScores &lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ScoreValue]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:gray;"&gt;)&lt;/span&gt; &lt;span style="color:blue;"&gt;values&lt;/span&gt; &lt;span style="color:gray;"&gt;(&lt;/span&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green;"&gt;/* ScoreValue - int */&lt;/span&gt; @currentScore &lt;span style="color:gray;"&gt;)&lt;/span&gt;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;end&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;set&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; @currentScore &lt;span style="color:gray;"&gt;=&lt;/span&gt; 50&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;insert&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &lt;span style="color:blue;"&gt;into&lt;/span&gt; @TempScores &lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ScoreValue]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:gray;"&gt;)&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;select&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &lt;span style="color:blue;"&gt;top&lt;/span&gt; 5 [ScoreValue] &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp; &lt;span style="color:blue;"&gt;from&lt;/span&gt; @PlayerScores&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&lt;span style="color:blue;"&gt;where&lt;/span&gt; [ScoreValue] &lt;span style="color:gray;"&gt;&amp;gt;&lt;/span&gt; @currentScore&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&lt;span style="color:blue;"&gt;order&lt;/span&gt; &lt;span style="color:blue;"&gt;by&lt;/span&gt; [ScoreValue] &lt;span style="color:blue;"&gt;asc&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;insert&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &lt;span style="color:blue;"&gt;into&lt;/span&gt; @TempScores &lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ScoreValue]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:gray;"&gt;)&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;select&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &lt;span style="color:blue;"&gt;top&lt;/span&gt; 5 [ScoreValue] &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp; &lt;span style="color:blue;"&gt;from&lt;/span&gt; @PlayerScores&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&lt;span style="color:blue;"&gt;where&lt;/span&gt; [ScoreValue] &lt;span style="color:gray;"&gt;&amp;lt;=&lt;/span&gt; @currentScore&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&lt;span style="color:blue;"&gt;order&lt;/span&gt; &lt;span style="color:blue;"&gt;by&lt;/span&gt; [ScoreValue] &lt;span style="color:blue;"&gt;desc&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;select&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt; &lt;span style="color:gray;"&gt;*&lt;/span&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp; &lt;span style="color:blue;"&gt;from&lt;/span&gt; @TempScores&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&amp;nbsp;&lt;span style="color:blue;"&gt;order&lt;/span&gt; &lt;span style="color:blue;"&gt;by&lt;/span&gt; [ScoreValue]&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://strangenut.com/aggbug.aspx?PostID=32" width="1" height="1"&gt;</content><author><name>dacrowlah</name><uri>http://strangenut.com/members/dacrowlah/default.aspx</uri></author><category term="T-SQL" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/T-SQL/default.aspx" /><category term="database" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/database/default.aspx" /><category term="SQL Server" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/SQL+Server/default.aspx" /></entry><entry><title>The Basics of Database Normalization - Explained</title><link rel="alternate" type="text/html" href="/blogs/dacrowlah/archive/2008/07/30/the-basics-of-database-normalization-explained.aspx" /><id>/blogs/dacrowlah/archive/2008/07/30/the-basics-of-database-normalization-explained.aspx</id><published>2008-07-30T22:05:00Z</published><updated>2008-07-30T22:05:00Z</updated><content type="html">&lt;p&gt;&lt;b&gt;Data Normalization&lt;/b&gt;, refers to creating a structure to store your data in that results in reduction/elimination of redundant data.&amp;nbsp; In a pure normalized form, a piece of data exists only in one place.&amp;nbsp;&amp;nbsp; Anywhere that the data is displayed is only making a reference to that data and joining tables together to recreate a human readable data structure.&amp;nbsp; You gain several things from having a well normalized database schema, and you lose some things.&amp;nbsp; Things that you gain are forced integrity of your data, everything belongs to something, attribute values are enforced to be in a known set of choices, and things are generally more clean and structured.&amp;nbsp; Things you lose.. simplicity.&amp;nbsp; The process of normalization results in generation of more tables, and so querying against data stored in these becomes more complex as you need to start doing joins and knowing what data will be there, what data might not be there;&amp;nbsp; you can sometimes start getting very odd results if you are not careful.&lt;/p&gt;
&lt;p&gt;As with many other subjects, there is a set of vocabulary terms that are used to express complex concepts succintly; data normalization is no different. There are varying degrees of normalization, each one being progressively more strict about what conditions must be met to attain a given level; these are referred to as &amp;quot;Normal Forms&amp;quot;.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&lt;b&gt;First Normal Form&lt;/b&gt; - typically abbreviated as &lt;b&gt;1NF&lt;/b&gt;, this is the most basic form, stating simply that a table must enforce that each row be unique, and not allow nulls in any column.&amp;nbsp; So, an example to illustrate this lets take a table that most of you will have worked with at one point or another: Addresses.&amp;nbsp; We will define the structure of the table as such:&lt;/p&gt;
&lt;pre&gt;create table Addresses&lt;br /&gt;(&lt;br /&gt;	AddressId int identity(1,1) not null primary key,&lt;br /&gt;	StreetAddress1 nvarchar(100) not null,&lt;br /&gt;	StreetAddress2 nvarchar(100) not null,&lt;br /&gt;	City nvarchar(100) not null,&lt;br /&gt;	State nvarchar(100) not null,&lt;br /&gt;	Zip nvarchar(100) not null,&lt;br /&gt;	IsMailingAddress bit not null,&lt;br /&gt;	IsBillingAddress bit not null,&lt;br /&gt;	IsPrimaryAddress bit not null	&lt;br /&gt;)&lt;br /&gt;go&lt;/pre&gt;
&lt;p&gt;This table adheres to the basic definition of 1NF, it has an identity column that has a unique key on it, which by definition, enforces that the row will be unique, even if the data is duplicated in every other column.&amp;nbsp; If we changed the table to allow the IsMailingAddress (or any other column for that matter to contain a null value, then this table would no longer be properly normalized.&amp;nbsp; There is some degree of contention about 1NF though; some people argue that &lt;a target="_blank" title="Wikipedia Entry for Edgar Codd" href="http://en.wikipedia.org/wiki/Edgar_F._Codd"&gt;Dr. Edgar F. Codd&lt;/a&gt; (the man who worked for IBM and invented the idea of relational data models) stated that null values must be allowed in a relational database.&amp;nbsp; If you go with this concept, you will never be able to achieve a fully normalized database.&amp;nbsp; For the sake of this discussion though, we will avoid a detailed explanation of this so as to keep things in scope.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Second Normal Form -&lt;/b&gt; also referred to as 2NF, this states that, first, the table must meet the guidelines of 1NF to be considered 2NF compliant.&amp;nbsp; Further, that all columns in the table must rely on the key to express their uniqueness as a row in the table.&amp;nbsp; Lets think about it like this if you have a table &lt;i&gt;[Employees]&lt;/i&gt; with the columns &lt;i&gt;[EmployeeId],[EmployeeName],&lt;/i&gt; and &lt;i&gt;[Skill]&lt;/i&gt;, and that a row in the table relied on a combination of EmployeeId and Skill to express uniqueness as a row, then the table is not meet the guidelines for 2NF.&amp;nbsp; Due to the fact that EmployeeName does not depend on Skill, it only depends on EmployeeId (other employees can have the same skill, but other employees cannot have the same EmployeeId)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Third Normal Form -&lt;/b&gt; 3NF is the more commonly used structure when designing a new data model.&amp;nbsp; It states that first a table must meet the requirements of 2NF, and goes one step further to state that all transitive or otherwise extraneous attributes have to be eliminated, and split off into what are commonly called Type tables.&amp;nbsp; Let&amp;#39;s look at again at the table above; notice how we have 3 columns that are attributes of an address &lt;i&gt;IsMailingAddress, IsBillingAddress, &lt;/i&gt;and &lt;i&gt;IsPrimaryAddress&lt;/i&gt;.&amp;nbsp; These 3 columns are transitive properties, and would need to be removed from this table.&amp;nbsp; We would first create a table &lt;i&gt;AddressType&lt;/i&gt;, and have the columns &lt;i&gt;AddressTypeId, AddressTypeName,&amp;nbsp; &lt;/i&gt;and perhaps an &lt;i&gt;AddressTypeDescription&lt;/i&gt; column.&amp;nbsp; Next, we would create a table &lt;i&gt;AddressTypes &lt;/i&gt;(note, these naming conventions can be adapted to best suit you, this is simply a convention that I have become accustomed to and ultimately I prefer a verbose name that directly implies what type of data we are working with), this table would have only two columns &lt;i&gt;AddressId&lt;/i&gt;, and &lt;i&gt;AddressTypeId&lt;/i&gt;.&lt;i&gt;&amp;nbsp; &lt;/i&gt;The goal of this is to only explicitly state what types the address IS, not also specify what they are NOT.&amp;nbsp;&amp;nbsp; Since not every address is a billing address, its extraneous data... we just don&amp;#39;t care.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;In most cases, 3NF is the most you will ever need to know about.&amp;nbsp; There are additional ones though, but their definitions are difficult to explain in concise terms to those new to database design, so I will address those later in detail.&amp;nbsp; Briefly though, they are Boyce-Codd Normal Form (BCNF), Fourth Normal Form (4NF), Fifth Normal Form (5NF), and Sixth Normal Form (6NF).&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://strangenut.com/aggbug.aspx?PostID=30" width="1" height="1"&gt;</content><author><name>dacrowlah</name><uri>http://strangenut.com/members/dacrowlah/default.aspx</uri></author><category term="database" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/database/default.aspx" /><category term="SQL Server" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/SQL+Server/default.aspx" /><category term="beginner" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/beginner/default.aspx" /></entry><entry><title>Engineering Managers: Top Ten Things Your DBA Should Be Doing</title><link rel="alternate" type="text/html" href="/blogs/dacrowlah/archive/2008/06/24/engineering-managers-top-ten-things-your-dba-should-be-doing.aspx" /><id>/blogs/dacrowlah/archive/2008/06/24/engineering-managers-top-ten-things-your-dba-should-be-doing.aspx</id><published>2008-06-24T17:28:00Z</published><updated>2008-06-24T17:28:00Z</updated><content type="html">&lt;p&gt;Recently I got a request for a top 10 list of things that a DBA should be doing on a daily basis from an engineering managers perspective.&amp;nbsp; Well, here is what I came up with, and please note, that this list is dependant on the poor guy being a full-time DBA, not some programmer who also doubles as a DBA as many of these tasks can be fairly time intensive depending on the size of the SQL Server installation and number of servers/databases/jobs that the DBA has to maintain.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;1.) Ensuring backups are running (and complete successfully)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Recently a round of SQL injection attacks put our backup/recovery strategy to the test and uncovered a few flaws that we hadn&amp;#39;t really encountered before. Namely, applications that continuously try and maintain connections to the database (note: a database should be in single user mode to do a recovery properly as the restore process needs to have exclusive access)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;2.) Ensuring storage space/RAM is not a concern&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Here at my job, when we launch a new site it&amp;#39;s usually (these days) a statewide deployment, with the states Governor, senators, lobbyists, and other political figures present, which means lots of news coverage, promotional material distribution, and the like.&amp;nbsp; Which always results in a sizable spike in traffic for about a month afterwards, then it normalizes again but is on average higher than it was before.&amp;nbsp; Starting late last year, this spike in traffic made the SQL Server logs grow exponentially and eventually took down the site due to a non-proactive system administrator and no full-time DBA.&amp;nbsp; It&amp;#39;s a good idea to keep this kind of thing as automated as possible.&amp;nbsp; As a matter of fact, all new HP Servers come with Insight Manager which can do this for you; I&amp;#39;d suggest finding someone capable to configure it for you.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;3.) Proactively monitoring database performance&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;This is somewhat of an open ended statement, and can mean a lot of different things to different people.&amp;nbsp; Work with your DBA to determine a set of metrics that are important to you for knowing what&amp;#39;s going on in the database.&amp;nbsp; Starting with SQL Server 2005, there is a rich set of data from the DMVs (Dynamic Management Views) available for snapshots into the internals of SQL Server.&amp;nbsp; If you cannot find anything to start with take a look on &lt;a target="_blank" title="Microsoft Developer Network" href="http://msdn.microsoft.com/"&gt;MSDN&lt;/a&gt; for information on whats available, from there you will get some ideas.&amp;nbsp; Some suggestions to start are the Top 100 Most resource intensive queries on your system. Start with the queries that are utilizing the highest amount of IO, as disk access is the slowest part of a database usually.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;4.) Ensuring that a usable disaster recovery plan is in place&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;This takes time, resources, planning, and people dedicated enough to the job to want to do it in off hours and on weekends, otherwise you could have some upset customers when your site goes down for &amp;quot;Testing&amp;quot;.&amp;nbsp; It is pretty important though, as who wants to be the one to tell the Boss that the site won&amp;#39;t come back up cause you can&amp;#39;t figure out why the database restore software gives a generic error message?&amp;nbsp; I didn&amp;#39;t want to, but I was that guy!&lt;/p&gt;
&lt;p&gt;&lt;b&gt;5.) Ensuring an adequate set of tools are available and are familiar with their functionality&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Every profession has its set of tools and utilities that make life easier.&amp;nbsp; Database professionals ... are... well... often left out.&amp;nbsp; However, there are some good tools out there for them, you just have to look for them!&amp;nbsp;&amp;nbsp; &lt;a target="_blank" title="Red-Gate Software" href="http://www.red-gate.com/products/index.htm"&gt;Red-Gate&lt;/a&gt; is an excellent starting point, their one product, &lt;a target="_blank" title="Red-Gate Software - SQL-Prompt" href="http://www.red-gate.com/products/SQL_Prompt/index.htm"&gt;SQL-Prompt&lt;/a&gt; is a godsend for people who do a lot of T-SQL development and use SQL Server Management Studio.&amp;nbsp; IntelliSense for T-SQL! YAAY! (note: SQL Server 2008 Management Studio has this built in when connected to a 2008 Server)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;6.) Ensuring that all database changes submitted by developers are reviewed and signed off on &lt;/b&gt;&lt;/p&gt;
&lt;p&gt;This is also somewhat open-ended, and is dependant on your organization having a structured change management process.&amp;nbsp; Let&amp;#39;s face it though, not all developers take the time to really understand how to properly program in SQL, and may not be making best use of existing indexes, so make sure your DBA looks over all the new SQL code before it goes to production.&amp;nbsp; It can save time on hard-to-locate performance hits later.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;7.) Identifying rapidly growing objects in the database (transaction logs, tables, etc)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;This goes hand in hand with #2, however, this is more of a proactive approach, usually automation techniques will let you know when you&amp;#39;re starting to approach a pre-determined threshold.&amp;nbsp; Doing this proactively, you will know when that time is coming, and you can have a strategy in place to handle it.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;8.) Ensuring scheduled tasks&amp;nbsp;are running (and complete successfully)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Backups, data cleansing, ETL tasks, all of them.&amp;nbsp; No one likes coming in in the morning and finding an application down because a nightly dataload did not complete properly or a partner did not upload it. Be ready to roll back any partial updates!&lt;/p&gt;
&lt;p&gt;&lt;b&gt;9.) Ensuring the disaster recovery plan actually works&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;I reiterate because I love you. No, really, I do. I mean it. Call me?&lt;/p&gt;
&lt;p&gt;&lt;b&gt;10.) Be familiar with what your platform can do&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Sounds simple enough, but I can&amp;#39;t tell you the number of times I&amp;#39;ve interviewed potential candidates, and they couldn&amp;#39;t tell me the difference between an inner join and an outer join.&amp;nbsp; But a DBA that can&amp;#39;t tell me what Profiler is? Nah.. not acceptable. If nothing else, know the toolsets that came with the product like the back of your hand, sometimes they&amp;#39;re too generic for a specific task, but I will lay money on them being useful 99% of the time!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://strangenut.com/aggbug.aspx?PostID=29" width="1" height="1"&gt;</content><author><name>dacrowlah</name><uri>http://strangenut.com/members/dacrowlah/default.aspx</uri></author><category term="T-SQL" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/T-SQL/default.aspx" /><category term="database" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/database/default.aspx" /><category term="SQL Server" scheme="http://strangenut.com/blogs/dacrowlah/archive/tags/SQL+Server/default.aspx" /></entry></feed>
