<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlblogcasts.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Alex_Kuznetsov</title><subtitle type="html" /><id>http://sqlblogcasts.com/blogs/alex_kuznetsov/atom.aspx</id><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/alex_kuznetsov/default.aspx" /><link rel="self" type="application/atom+xml" href="http://sqlblogcasts.com/blogs/alex_kuznetsov/atom.aspx" /><generator uri="http://communityserver.org" version="3.1.20917.1142">Community Server</generator><updated>2007-08-24T11:57:00Z</updated><entry><title>Remove all non-numeric characters from a string.</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2008/02/23/remove-all-non-numeric-characters-from-a-string.aspx" /><id>http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2008/02/23/remove-all-non-numeric-characters-from-a-string.aspx</id><published>2008-02-23T16:50:00Z</published><updated>2008-02-23T16:50:00Z</updated><content type="html">&lt;p&gt;The problem came up on newsgroups. The set based solution is quite simple:&lt;/p&gt;&lt;p&gt;SELECT REPLICATE('0', COUNT(*) - MAX(CASE WHEN c&amp;lt;&amp;gt;'0' THEN n ELSE 0 &lt;br&gt; END)) &lt;br&gt; + &lt;br&gt; CAST((SUM(CAST((c + LEFT('00000000000000000',n)) AS INT)) /10) AS &lt;br&gt; VARCHAR(100)) &lt;br&gt; FROM( &lt;br&gt; SELECT c, ROW_NUMBER()OVER(ORDER BY Number DESC) AS n FROM(SELECT &lt;br&gt; SUBSTRING('asdf004506õÎÉÏÃÄÅ8sd',Number, 1) AS c, Number FROM &lt;br&gt; Data.Numbers) t &lt;br&gt; WHERE c IN('0','1','2','3','4','5','6','7','8','9') &lt;br&gt; ) t &lt;br&gt; &lt;/p&gt;----------------- &lt;br&gt; 0045068 &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;It assumes that there is an auxiliary table  Data.Numbers. &lt;br&gt;&lt;/p&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=7712" width="1" height="1"&gt;</content><author><name>Alex_Kuznetsov</name><uri>http://sqlblogcasts.com/members/Alex_5F00_Kuznetsov.aspx</uri></author></entry><entry><title>Vote for TOP(@n) OVER(PARTITION BY ... ORDER BY ...) syntax</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2008/02/23/vote-for-top-n-over-partition-by-order-by-syntax.aspx" /><id>http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2008/02/23/vote-for-top-n-over-partition-by-order-by-syntax.aspx</id><published>2008-02-23T16:46:00Z</published><updated>2008-02-23T16:46:00Z</updated><content type="html">&lt;p&gt;&lt;a href="http://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=254390" rel="nofollow" target="_new"&gt;http://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=254390&lt;/a&gt;&lt;/p&gt;&lt;div class="data-box"&gt;
            &lt;div class="data-item"&gt;
                &lt;div class="Header"&gt;Description&lt;/div&gt;
                &lt;div class="Body"&gt;To address a very common requirement, Itzik Ben-Gan is suggesting the following syntax:&lt;br&gt;&lt;br&gt;TOP(@n) OVER(PARTITION BY ... ORDER BY ...)&lt;br&gt;&lt;br&gt;For instance, the requirement "select three latest orders for every customer" would be implemented as&lt;br&gt;&lt;br&gt;SELECT TOP(3) OVER(PARTITION BY CustomerID ORDER BY OrderDate DESC) ...&lt;br&gt;&lt;br&gt;Advantages:
all intentions are expressed in one place, in an intuitively clear
way, similar to existing OLAP functions syntax. The alternative is to
use ROW_NUMBER(), and the implementation of the requirement is
scattered all over the query, nd requires an inline view. &lt;br&gt;&lt;br&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=7711" width="1" height="1"&gt;</content><author><name>Alex_Kuznetsov</name><uri>http://sqlblogcasts.com/members/Alex_5F00_Kuznetsov.aspx</uri></author></entry><entry><title>Test Coverage: 100%</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2008/02/12/test-coverage-100.aspx" /><id>http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2008/02/12/test-coverage-100.aspx</id><published>2008-02-12T23:27:00Z</published><updated>2008-02-12T23:27:00Z</updated><content type="html">&lt;p&gt;In my C# projects I am using NCover (http://www.ncover.com/). It shows me which lines of code are executed by my unit tests (I am using NUnit). I added more unit tests in which my stored procedures blow up and raise exceptions. Now all my catch() branches are executed, and the coverage is 100%. Every line in my source code is executed at least once.&lt;br&gt; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=7243" width="1" height="1"&gt;</content><author><name>Alex_Kuznetsov</name><uri>http://sqlblogcasts.com/members/Alex_5F00_Kuznetsov.aspx</uri></author></entry><entry><title>Using a Foreign key constraint to check validity of History Windows (Start - End Date Windows)</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2008/02/07/using-a-foreign-key-constraint-to-check-validity-of-history-windows-start-end-date-windows.aspx" /><id>http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2008/02/07/using-a-foreign-key-constraint-to-check-validity-of-history-windows-start-end-date-windows.aspx</id><published>2008-02-07T16:07:00Z</published><updated>2008-02-07T16:07:00Z</updated><content type="html">CREATE TABLE dbo.TaskStatuses(TaskID INT NOT NULL, &lt;br&gt;&amp;nbsp; Status VARCHAR(20),&lt;br&gt;&amp;nbsp; StartedAt DATETIME NOT NULL,&lt;br&gt;&amp;nbsp; FinishedAt DATETIME NOT NULL,&lt;br&gt;&amp;nbsp; PreviousFinishedAt DATETIME NULL,&lt;br&gt;&amp;nbsp; CONSTRAINT PK_TaskStatuses_TaskID_FinishedAt PRIMARY KEY(TaskID, FinishedAt),&lt;br&gt;&amp;nbsp; CONSTRAINT UNQ_TaskStatuses_TaskID_PreviousFinishedAt UNIQUE(TaskID, PreviousFinishedAt),&lt;br&gt;&amp;nbsp; CONSTRAINT FK_TaskStatuses_TaskID_PreviousFinishedAt &lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;FOREIGN KEY(TaskID, PreviousFinishedAt) &lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;REFERENCES dbo.TaskStatuses(TaskID, FinishedAt),&lt;br&gt;&amp;nbsp; CONSTRAINT CHK_TaskStatuses_PreviousFinishedAt_Before_StartedAt CHECK(PreviousFinishedAt &amp;lt;= StartedAt)&lt;br&gt;)&lt;br&gt;go&lt;br&gt;&lt;br&gt;INSERT INTO dbo.TaskStatuses(TaskID, Status, StartedAt, FinishedAt, PreviousFinishedAt)&lt;br&gt;&amp;nbsp; VALUES(1, 'Pending', '20070101', '20070103', NULL)&lt;br&gt;&lt;br&gt;-- you cannot have more than one beginning of history chain per task:&lt;br&gt;INSERT INTO dbo.TaskStatuses(TaskID, Status, StartedAt, FinishedAt, PreviousFinishedAt)&lt;br&gt;&amp;nbsp; VALUES(1, 'Pending', '20070104', '20070105', NULL)&lt;br&gt;/*&lt;br&gt;Server: Msg 2627, Level 14, State 2, Line 1&lt;br&gt;Violation of UNIQUE KEY constraint 'UNQ_TaskStatuses_TaskID_PreviousFinishedAt'. Cannot insert duplicate key in object 'TaskStatuses'.&lt;br&gt;The statement has been terminated.&lt;br&gt;*/&lt;br&gt;INSERT INTO dbo.TaskStatuses(TaskID, Status, StartedAt, FinishedAt, PreviousFinishedAt)&lt;br&gt;&amp;nbsp; VALUES(1, 'Pending', '20070104', '20070105', '20070103')&lt;br&gt;&lt;br&gt;-- history windows cannot overlap:&lt;br&gt;INSERT INTO dbo.TaskStatuses(TaskID, Status, StartedAt, FinishedAt, PreviousFinishedAt)&lt;br&gt;&amp;nbsp; VALUES(1, 'Opened', '20070104', '20070109', '20070105')&lt;br&gt;/*&lt;br&gt;Server: Msg 547, Level 16, State 1, Line 1&lt;br&gt;INSERT statement conflicted with TABLE CHECK constraint 'CHK_TaskStatuses_PreviousFinishedAt_Before_StartedAt'. The conflict occurred in database 'RiskCenter', table 'TaskStatuses'.&lt;br&gt;The statement has been terminated.&lt;br&gt;*/&lt;br&gt;INSERT INTO dbo.TaskStatuses(TaskID, Status, StartedAt, FinishedAt, PreviousFinishedAt)&lt;br&gt;&amp;nbsp; VALUES(1, 'Opened', '20070114', '20070119', '20070105')&lt;br&gt;&lt;br&gt;-- you cannot fill a gap in one insert&lt;br&gt;-- Gap between Jan 5 and Jan 14&lt;br&gt;&lt;br&gt;INSERT INTO dbo.TaskStatuses(TaskID, Status, StartedAt, FinishedAt, PreviousFinishedAt)&lt;br&gt;&amp;nbsp; VALUES(1, 'Reviewed', '20070105', '20070114', '20070105')&lt;br&gt;/*&lt;br&gt;Server: Msg 2627, Level 14, State 2, Line 1&lt;br&gt;Violation of UNIQUE KEY constraint 'UNQ_TaskStatuses_TaskID_PreviousFinishedAt'. Cannot insert duplicate key in object 'TaskStatuses'.&lt;br&gt;The statement has been terminated.&lt;br&gt;*/&lt;br&gt;&lt;br&gt;-- to fill a gap, add to the end of the chain:&lt;br&gt;INSERT INTO dbo.TaskStatuses(TaskID, Status, StartedAt, FinishedAt, PreviousFinishedAt)&lt;br&gt;&amp;nbsp; VALUES(1, 'Reviewed', '20070125', '20070129', '20070119')&lt;br&gt;&lt;br&gt;/*&lt;br&gt;TaskID&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Status&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; StartedAt FinishedAt PreviousFinishedAt&lt;br&gt;----------- -------------------- --------- ---------- ------------------&lt;br&gt;1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Pending&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; 20070101&amp;nbsp; 20070103&amp;nbsp;&amp;nbsp; NULL&lt;br&gt;1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Pending&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; 20070104&amp;nbsp; 20070105&amp;nbsp;&amp;nbsp; 20070103&lt;br&gt;1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Opened&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; 20070114&amp;nbsp; 20070119&amp;nbsp;&amp;nbsp; 20070105&lt;br&gt;1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Reviewed&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 20070125&amp;nbsp; 20070129&amp;nbsp;&amp;nbsp; 20070119&lt;br&gt;&lt;br&gt;(4 row(s) affected)&lt;br&gt;*/&lt;br&gt;&lt;br&gt;&lt;br&gt;-- then move the last period to fill the gap&lt;br&gt;UPDATE dbo.TaskStatuses SET StartedAt = CASE WHEN FinishedAt = '20070129' THEN '20070105' ELSE StartedAt END, &lt;br&gt;&amp;nbsp; FinishedAt = CASE WHEN FinishedAt = '20070129' THEN '20070114' ELSE FinishedAt END, &amp;nbsp;&lt;br&gt;&amp;nbsp; PreviousFinishedAt = CASE WHEN FinishedAt = '20070129' THEN '20070105' ELSE '20070114' END&lt;br&gt;WHERE TaskID = 1 AND FinishedAt IN('20070129', '20070119')&lt;br&gt;&lt;br&gt;SELECT TaskID, Status, CONVERT(CHAR(8), StartedAt, 112) StartedAt, &lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;CONVERT(CHAR(8), FinishedAt, 112) FinishedAt, &lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;CONVERT(CHAR(8), PreviousFinishedAt, 112) PreviousFinishedAt &lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;FROM dbo.TaskStatuses ORDER BY FinishedAt&lt;br&gt;&lt;br&gt;/*&lt;br&gt;TaskID&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Status&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; StartedAt FinishedAt PreviousFinishedAt &lt;br&gt;----------- -------------------- --------- ---------- ------------------ &lt;br&gt;1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Pending&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; 20070101&amp;nbsp; 20070103&amp;nbsp;&amp;nbsp; NULL&lt;br&gt;1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Pending&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; 20070104&amp;nbsp; 20070105&amp;nbsp;&amp;nbsp; 20070103&lt;br&gt;1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Reviewed&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 20070105&amp;nbsp; 20070114&amp;nbsp;&amp;nbsp; 20070105&lt;br&gt;1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Opened&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; 20070114&amp;nbsp; 20070119&amp;nbsp;&amp;nbsp; 20070114&lt;br&gt;&lt;br&gt;(4 row(s) affected)&lt;br&gt;*/&lt;br&gt;&lt;br&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=6901" width="1" height="1"&gt;</content><author><name>Alex_Kuznetsov</name><uri>http://sqlblogcasts.com/members/Alex_5F00_Kuznetsov.aspx</uri></author></entry><entry><title>List of tables without primary keys</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2008/02/06/list-of-tables-without-primary-keys.aspx" /><id>http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2008/02/06/list-of-tables-without-primary-keys.aspx</id><published>2008-02-06T20:56:00Z</published><updated>2008-02-06T20:56:00Z</updated><content type="html">&lt;p&gt;SELECT &lt;br&gt;t.TABLE_SCHEMA, t.TABLE_NAME, tc.CONSTRAINT_NAME&lt;br&gt;FROM INFORMATION_SCHEMA.TABLES t&lt;br&gt;LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc &lt;br&gt;&amp;nbsp; ON t.TABLE_SCHEMA = tc.TABLE_SCHEMA &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; AND t.TABLE_NAME = tc.TABLE_NAME &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; AND tc.CONSTRAINT_TYPE = 'PRIMARY KEY'&lt;br&gt;WHERE t.TABLE_TYPE = 'BASE TABLE' &lt;br&gt;AND tc.CONSTRAINT_NAME IS NULL&lt;br&gt;ORDER BY t.TABLE_NAME&lt;/p&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=6859" width="1" height="1"&gt;</content><author><name>Alex_Kuznetsov</name><uri>http://sqlblogcasts.com/members/Alex_5F00_Kuznetsov.aspx</uri></author></entry><entry><title>When SUM of Six Floats Depends on Order of Adding</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2007/10/26/when-sum-of-six-floats-depends-on-order-of-adding.aspx" /><id>http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2007/10/26/when-sum-of-six-floats-depends-on-order-of-adding.aspx</id><published>2007-10-26T21:07:00Z</published><updated>2007-10-26T21:07:00Z</updated><content type="html">&lt;p&gt;Following the discussion started by Hugo Kornelis and Old Grumpy DBA, an example of inexact calculations with float datatype:&lt;br&gt;&lt;/p&gt;&lt;p&gt;declare @big float, @small float, @sum1 float, @sum2 float, @sum3 float, @i INT&lt;br&gt;SELECT @big = 12345678901234.50, @small = 0.01, @i = 0&lt;br&gt;SELECT @sum1 = @big, @sum2 = 0, @sum3 = 0&lt;br&gt;WHILE @i &amp;lt; 5 BEGIN&lt;br&gt;&amp;nbsp; SELECT @sum1 = @sum1 + @small, @sum2 = @sum2 + @small, @sum3 = @sum3 + @small&lt;br&gt;&amp;nbsp; SET @i = @i + 1&lt;br&gt;END&lt;br&gt;SELECT @sum2 = @sum2 + @big&lt;br&gt;SELECT @sum1, @sum2, @sum3&lt;br&gt;&lt;br&gt;---------------------- ---------------------- ----------------------&lt;br&gt;12345678901234.5&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 12345678901234.6&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.05&lt;br&gt;&lt;br&gt;(1 row(s) affected)&lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;This is why you cannot have sums of floats in indexed views - they are not deterministic, they may depend on order of adding.&lt;br&gt;&lt;/p&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=3015" width="1" height="1"&gt;</content><author><name>Alex_Kuznetsov</name><uri>http://sqlblogcasts.com/members/Alex_5F00_Kuznetsov.aspx</uri></author></entry><entry><title>When It Is OK to Use SELECT * in Production Code.</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2007/10/19/can-i-use-select-in-my-production-code.aspx" /><id>http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2007/10/19/can-i-use-select-in-my-production-code.aspx</id><published>2007-10-19T15:54:00Z</published><updated>2007-10-19T15:54:00Z</updated><content type="html">If you google up 'never use SELECT * in production code' you will get many many hits.&lt;br&gt;Clearly in many cases using SELECT * makes your code vulnerable to changes in underlying table(s) and as such should be avoided.&lt;br&gt;Yet I don't think the common rule of thumb 'never use SELECT * in production code' should be used &lt;br&gt;without thinking, I don't think it should be blindly applied in all the situations.&lt;br&gt;For instanse, consider a request to display top five sales for every region and a simple query that satisfies it&lt;br&gt;&lt;br&gt;SELECT SalesAmount, RegionName, LongListOfOtherColumns&lt;br&gt;FROM(&lt;br&gt;SELECT SalesAmount, RegionName, LongListOfOtherColumns,&lt;br&gt;&amp;nbsp; ROW_NUMBER() OVER(PARTITION BY RegionName ORDER BY SalesAmount DESC) AS rn&lt;br&gt;FROM Sales.Sales&lt;br&gt;) t WHERE rn &amp;lt; 6&lt;br&gt;&lt;br&gt;Does repeating SalesAmount, RegionName, LongListOfOtherColumns twice make your code nay better/safer/readable?&lt;br&gt;I don't think so. Consider the following alternative:&lt;br&gt;&lt;br&gt;SELECT *&lt;br&gt;FROM(&lt;br&gt;SELECT SalesAmount, RegionName, LongListOfOtherColumns,&lt;br&gt;&amp;nbsp; ROW_NUMBER() OVER(PARTITION BY RegionName ORDER BY SalesAmount DESC) AS rn&lt;br&gt;FROM Sales.Sales&lt;br&gt;) t WHERE rn &amp;lt; 6&lt;br&gt;&lt;br&gt;It is shorter, easier to maintain, and just as robust as the original query. &lt;br&gt;You have explicitly listed the columns&lt;br&gt;in your subquery, so you are already insulated from any changes in Sales.Sales table.&lt;br&gt;You don't need an additional layer of protection. &lt;br&gt;Repeating the list of columns twice only makes your code more prone to errors.&lt;br&gt;&lt;br&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=2825" width="1" height="1"&gt;</content><author><name>Alex_Kuznetsov</name><uri>http://sqlblogcasts.com/members/Alex_5F00_Kuznetsov.aspx</uri></author></entry><entry><title>Mimicking a table variable parameter with an image.</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2007/09/23/mimicking-a-table-variable-parameter-with-an-image.aspx" /><id>http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2007/09/23/mimicking-a-table-variable-parameter-with-an-image.aspx</id><published>2007-09-23T21:18:00Z</published><updated>2007-09-23T21:18:00Z</updated><content type="html">&lt;p&gt;Following a discussion with SQL Server MVP Joe Webb at PASS conference in Denver, I decided to re-post this approach including all the bells and whistles. Of course, the general idea of the approach was borrowed from Erland Sommarskog's article on Arrays and Lists in SQL.&lt;/p&gt;&lt;p&gt;1. Packing an array of numbers in an image. I have to change the order of bytes when I store an array of long integers in an array of bytes, as follows:&lt;/p&gt;&lt;pre&gt;static byte[] UlongsToBytes(ulong[] ulongs) {&lt;br&gt;   int ifrom = ulongs.GetLowerBound(0);&lt;br&gt;   int ito   = ulongs.GetUpperBound(0);&lt;br&gt;   int l = (ito - ifrom + 1)*8;&lt;br&gt;   byte[] ret = new byte[l];&lt;br&gt;   int retind = 0;&lt;br&gt;   for(int i=ifrom; i&amp;lt;=ito; i++)&lt;br&gt;   {&lt;br&gt;           ulong v = ulongs[ i ];&lt;br&gt;           ret[retind++] = (byte) (v &amp;gt;&amp;gt; 0x38);&lt;br&gt;           ret[retind++] = (byte) (v &amp;gt;&amp;gt; 0x30);&lt;br&gt;           ret[retind++] = (byte) (v &amp;gt;&amp;gt; 40);&lt;br&gt;           ret[retind++] = (byte) (v &amp;gt;&amp;gt; 0x20);&lt;br&gt;           ret[retind++] = (byte) (v &amp;gt;&amp;gt; 0x18);&lt;br&gt;           ret[retind++] = (byte) (v &amp;gt;&amp;gt; 0x10);&lt;br&gt;           ret[retind++] = (byte) (v &amp;gt;&amp;gt; 8);&lt;br&gt;           ret[retind++] = (byte) v;&lt;br&gt;   }&lt;br&gt;&lt;br&gt;   return ret;&lt;/pre&gt;&lt;pre&gt;This code snippet is also included in Erland's article at&lt;/pre&gt;&lt;pre&gt;http://www.sommarskog.se/arrays-in-sql-2005.html&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;2. Binding the array of bytes as an image parameter:&lt;/pre&gt;&lt;pre&gt;static void Main(string[] args)&lt;br&gt;{&lt;br&gt;DateTime d1, d2, d3;&lt;br&gt;d1 = DateTime.Now;&lt;br&gt;d2 = DateTime.Now;&lt;br&gt;string sddd = d1.ToString();&lt;br&gt;ulong[] ul = new ulong[10000];&lt;br&gt;for(uint i=0; i&amp;lt;10000; i++)&lt;br&gt;{&lt;br&gt;ul[ i ] = i;&lt;br&gt;}&lt;br&gt;string sss = UlongsToString(ul);&lt;br&gt;byte[] ba = UlongsToBytes(ul);&lt;br&gt;string directInsert = UlongsToDirectInsert(ul);&lt;br&gt;try&lt;br&gt;{&lt;br&gt;string source = @"packet size=4096;integrated security=SSPI;data source=MyPC\MyNamedInstance;persist security info=False;initial catalog=Sandbox";&lt;br&gt;SqlConnection conn = new SqlConnection(source);&lt;br&gt;conn.Open();&lt;br&gt;SqlCommand a = new SqlCommand("INSERT BigintsTarget(bi) SELECT * FROM dbo.ParseImageIntoBIGINTs(@BIGINTs)", conn);&lt;br&gt;a.CommandType = System.Data.CommandType.Text;&lt;br&gt;a.Parameters.Add(new SqlParameter("@BIGINTs", System.Data.SqlDbType.Image,2147483647));&lt;br&gt;for(int q=0; q&amp;lt;10; q++)&lt;br&gt;{&lt;br&gt;a.Parameters[0].Value = ba;&lt;br&gt;int res = a.ExecuteNonQuery();&lt;br&gt;}&lt;br&gt;d2 = DateTime.Now;&lt;br&gt;SqlCommand b = new SqlCommand("INSERT BigintsTarget1(bi) SELECT * FROM dbo.ParseVarcharMAXIntoBIGINTs(@BIGINTs)", conn);&lt;br&gt;b.CommandType = System.Data.CommandType.Text;&lt;br&gt;b.Parameters.Add(new SqlParameter("@BIGINTs", System.Data.SqlDbType.VarChar,2147483647));&lt;br&gt;for(int q=0; q&amp;lt;10; q++)&lt;br&gt;{&lt;br&gt;b.Parameters[0].Value = sss;&lt;br&gt;int res = b.ExecuteNonQuery();&lt;br&gt;}&lt;br&gt;//b.ExecuteNonQuery();&lt;br&gt;conn.Close();&lt;br&gt;}&lt;br&gt;catch(Exception ex)&lt;br&gt;{&lt;br&gt;string s = ex.Message;&lt;br&gt;int t=0;&lt;br&gt;t++;&lt;br&gt;}&lt;br&gt;d3 = DateTime.Now;&lt;br&gt;string sdiff1 = d1.ToString() + " - " + d2.ToString();&lt;br&gt;string sdiff2 = d2.ToString() + " - " + d3.ToString();&lt;br&gt;string tttttt = "sdfa";&lt;br&gt;}&lt;br&gt;} &lt;br&gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;3. Objects on SQL Server side:&lt;/pre&gt;&lt;pre&gt;-- Assuming that there already is an auxiliary Numbers table:&lt;/pre&gt;&lt;pre&gt;SELECT Number*8 + 1 AS StartFrom, Number*8 + 8 AS MaxLen INTO dbo.ParsingNumbers FROM dbo.Numbers &lt;br&gt;&lt;/pre&gt;

&lt;p&gt;CREATE FUNCTION dbo.ParseImageIntoBIGINTs(@BIGINTs IMAGE)&lt;br&gt;RETURNS TABLE AS RETURN(&lt;br&gt;&amp;nbsp;SELECT CAST(SUBSTRING(@BIGINTs, StartFrom, 8) AS BIGINT) Num FROM dbo.ParsingNumbers WHERE MaxLen &amp;lt;= DATALENGTH(@BIGINTs))&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=2558" width="1" height="1"&gt;</content><author><name>Alex_Kuznetsov</name><uri>http://sqlblogcasts.com/members/Alex_5F00_Kuznetsov.aspx</uri></author></entry><entry><title>Yet another index covering tip</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2007/09/14/yet-another-index-covering-tip.aspx" /><id>http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2007/09/14/yet-another-index-covering-tip.aspx</id><published>2007-09-14T13:30:00Z</published><updated>2007-09-14T13:30:00Z</updated><content type="html">Suppose you want you NCI index cover a query. Suppose you want to make sure that a column, let's say CustomerID, is stored in the index.&lt;br&gt;Even if your table is currently clustered on CustomerID, it is still a good practice to explicitly include CustomerID in your NCI. The reason is simple: sometimes we can drop the CI and build another CI on another column(s). Your index should still store CustomerID, so that it still covers your query.&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=2523" width="1" height="1"&gt;</content><author><name>Alex_Kuznetsov</name><uri>http://sqlblogcasts.com/members/Alex_5F00_Kuznetsov.aspx</uri></author></entry><entry><title>Not qualifying column names with table aliases may lead to hard-to-find errors</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2007/09/14/not-qualifying-column-names-with-table-aliases-may-lead-to-hard-to-find-errors.aspx" /><id>http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2007/09/14/not-qualifying-column-names-with-table-aliases-may-lead-to-hard-to-find-errors.aspx</id><published>2007-09-14T13:22:00Z</published><updated>2007-09-14T13:22:00Z</updated><content type="html">CREATE TABLE #t1(i INT)&lt;br&gt;INSERT #t1 VALUES(1)&lt;br&gt;INSERT #t1 VALUES(2)&lt;br&gt;&lt;br&gt;CREATE TABLE #t2(i INT)&lt;br&gt;INSERT #t2 VALUES(1)&lt;br&gt;INSERT #t2 VALUES(3)&lt;br&gt;&lt;br&gt;-- incorrect result&lt;br&gt;SELECT i FROM #t1 &lt;br&gt;WHERE NOT EXISTS(SELECT 1 FROM #t2 WHERE #t2.i = i)&lt;br&gt;/*&lt;br&gt;i&lt;br&gt;-----------&lt;br&gt;&lt;br&gt;(0 row(s) affected)&lt;br&gt;*/&lt;br&gt;&lt;br&gt;-- correct result&lt;br&gt;SELECT i FROM #t1 t1&lt;br&gt;WHERE NOT EXISTS(SELECT 1 FROM #t2 WHERE #t2.i = t1.i)&lt;br&gt;/*&lt;br&gt;i&lt;br&gt;-----------&lt;br&gt;2&lt;br&gt;&lt;br&gt;(1 row(s) affected)&lt;br&gt;&lt;br&gt;*/&lt;br&gt;&lt;br&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=2522" width="1" height="1"&gt;</content><author><name>Alex_Kuznetsov</name><uri>http://sqlblogcasts.com/members/Alex_5F00_Kuznetsov.aspx</uri></author></entry><entry><title>The price of not qualifying stored procedure's names with schema names</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2007/09/03/the-price-of-not-qualifying-object-names-with-schema.aspx" /><id>http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2007/09/03/the-price-of-not-qualifying-object-names-with-schema.aspx</id><published>2007-09-03T17:19:00Z</published><updated>2007-09-03T17:19:00Z</updated><content type="html">&lt;p&gt;Just a very brief example:&lt;/p&gt;&lt;p&gt;1. Create 10K stored procedures.&amp;nbsp;&lt;/p&gt;&lt;p&gt;DECLARE @i INT, @SQL NVARCHAR(300)&lt;br&gt;SELECT @i = 0&lt;br&gt;WHILE @i &amp;lt; 10000 BEGIN&lt;br&gt;&amp;nbsp; SET @i = @i + 1&lt;br&gt;&amp;nbsp; SET @SQL = 'CREATE PROCEDURE dbo.DummyProc' + CAST(@i AS NVARCHAR(10)) + ' AS RETURN 0'&lt;br&gt;&amp;nbsp; EXEC sp_executesql @SQL&lt;br&gt;END&lt;br&gt;GO&lt;br&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;2. Run them.&lt;br&gt;&lt;/p&gt;&lt;p&gt;DECLARE @i INT, @j INT, @d DATETIME, @SQL NVARCHAR(300), @SQL_to_run NVARCHAR(300)&lt;br&gt;SELECT @i = 0, @j = 0, @d = getdate()&lt;br&gt;WHILE @j &amp;lt; 3 BEGIN&lt;br&gt;&amp;nbsp; SET @j = @j + 1&lt;br&gt;&amp;nbsp; IF @j = 1 BEGIN&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SET @SQL = 'EXEC DummyProc'&lt;br&gt;&amp;nbsp; END ELSE BEGIN&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SET @SQL = 'EXEC dbo.DummyProc'&lt;br&gt;&amp;nbsp; END&lt;br&gt;&amp;nbsp; WHILE @i &amp;lt; 10000 BEGIN&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SET @i = @i + 1&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SET @SQL_to_run = @SQL + CAST(@i AS NVARCHAR(10))&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; --PRINT @SQL_to_run&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IF @j &amp;lt;3 BEGIN&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EXEC sp_executesql @SQL_to_run&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; END&lt;br&gt;&amp;nbsp; END&lt;br&gt;&amp;nbsp; SELECT DATEDIFF(ms, @d, GEtdate()) as ms&lt;br&gt;&amp;nbsp; SELECT @i = 0, @d = getdate()&lt;br&gt;END&lt;br&gt;GO&lt;br&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;3. Clean up.&lt;br&gt;&lt;/p&gt;&lt;p&gt;DECLARE @i INT, @SQL NVARCHAR(300)&lt;br&gt;SELECT @i = 0&lt;br&gt;WHILE @i &amp;lt; 10000 BEGIN&lt;br&gt;&amp;nbsp; SET @i = @i + 1&lt;br&gt;&amp;nbsp; SET @SQL = 'DROP PROCEDURE dbo.DummyProc' + CAST(@i AS NVARCHAR(10)) &lt;br&gt;&amp;nbsp; EXEC sp_executesql @SQL&lt;br&gt;END&lt;br&gt;GO&lt;br&gt;&lt;/p&gt;&lt;p&gt;The results:&lt;/p&gt;&lt;p&gt;ms - no schema names&lt;br&gt;-----------&lt;br&gt;3860&lt;br&gt;&lt;br&gt;(1 row(s) affected)&lt;br&gt;&lt;br&gt;ms - with schema names&lt;br&gt;-----------&lt;br&gt;640&lt;br&gt;&lt;br&gt;(1 row(s) affected)&lt;br&gt;&lt;br&gt;ms - the overhead of running the loop without sp_executesql calls&lt;br&gt;-----------&lt;br&gt;46 &lt;br&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;However, if you repeatedly call one and the same procedure, you will not notice much difference one way or another:&lt;/p&gt;&lt;p&gt;CREATE PROCEDURE dbo.DummyProc&lt;br&gt;AS&lt;br&gt;RETURN 0&lt;br&gt;GO&lt;br&gt;CREATE PROCEDURE dbo.Run_SQL_100K_times&lt;br&gt;&amp;nbsp; @SQL NVARCHAR(30)&lt;br&gt;AS&lt;br&gt;DECLARE @i INT, @d DATETIME&lt;br&gt;SELECT @i = 0, @d = getdate()&lt;br&gt;WHILE @i &amp;lt; 100000 BEGIN&lt;br&gt;&amp;nbsp; SET @i = @i + 1&lt;br&gt;&amp;nbsp; EXEC sp_executesql @SQL&lt;br&gt;END&lt;br&gt;SELECT DATEDIFF(ms, @d, GEtdate()) as ms, @SQL AS SQL&lt;br&gt;GO&lt;br&gt;EXEC dbo.Run_SQL_100K_times 'EXEC DummyProc'&lt;br&gt;EXEC dbo.Run_SQL_100K_times 'EXEC dbo.DummyProc'&lt;br&gt;GO&lt;br&gt;DROP PROCEDURE dbo.Run_SQL_100K_times&lt;br&gt;DROP PROCEDURE dbo.DummyProc&lt;br&gt;GO&lt;br&gt;&lt;br&gt;ms&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SQL&lt;br&gt;----------- ------------------------------&lt;br&gt;2330&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EXEC DummyProc&lt;br&gt;&lt;br&gt;(1 row(s) affected)&lt;br&gt;&lt;br&gt;ms&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SQL&lt;br&gt;----------- ------------------------------&lt;br&gt;2310&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EXEC dbo.DummyProc&lt;br&gt;&lt;br&gt;(1 row(s) affected) &lt;br&gt;&lt;/p&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=2478" width="1" height="1"&gt;</content><author><name>Alex_Kuznetsov</name><uri>http://sqlblogcasts.com/members/Alex_5F00_Kuznetsov.aspx</uri></author></entry><entry><title>Our next article went live on simple-talk.com</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2007/09/02/our-next-article-went-live-on-simple-talk-com.aspx" /><id>http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2007/09/02/our-next-article-went-live-on-simple-talk-com.aspx</id><published>2007-09-03T00:02:00Z</published><updated>2007-09-03T00:02:00Z</updated><content type="html">&lt;p&gt;"Close These Loopholes - Testing Database Modifications"&amp;nbsp;&lt;/p&gt;&lt;p&gt;http://www.simple-talk.com/sql/t-sql-programming/close-these-loopholes---testing-database-modifications/&lt;/p&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=2475" width="1" height="1"&gt;</content><author><name>Alex_Kuznetsov</name><uri>http://sqlblogcasts.com/members/Alex_5F00_Kuznetsov.aspx</uri></author></entry><entry><title>Using a placeholder</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2007/08/30/using-a-placeholder.aspx" /><id>http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2007/08/30/using-a-placeholder.aspx</id><published>2007-08-30T20:54:00Z</published><updated>2007-08-30T20:54:00Z</updated><content type="html">&lt;p&gt;I usually create a few files, let's say 5 GB each, on my hard drive. Whenever I run out of disk space, I can just drop a couple of those and keep working - that buys me some time. If I am in a hurry, dropping a placeholder file is a quick fix. &lt;/p&gt;&lt;p&gt;Of course, at some later time I need to clean up my hard drive, and re-create dropped placeholder files. &lt;br&gt;&lt;/p&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=2433" width="1" height="1"&gt;</content><author><name>Alex_Kuznetsov</name><uri>http://sqlblogcasts.com/members/Alex_5F00_Kuznetsov.aspx</uri></author></entry><entry><title>Selecting a random number for each row</title><link rel="alternate" type="text/html" href="http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2007/08/24/Selecting-a-random-number-for-each-row.aspx" /><id>http://sqlblogcasts.com/blogs/alex_kuznetsov/archive/2007/08/24/Selecting-a-random-number-for-each-row.aspx</id><published>2007-08-24T16:57:00Z</published><updated>2007-08-24T16:57:00Z</updated><content type="html">&lt;br&gt;&lt;p&gt;create view wrapped_rand_view&lt;br&gt;as&lt;br&gt;select rand( ) as random_value&lt;br&gt;go&lt;br&gt;create function wrapped_rand()&lt;br&gt;returns float&lt;br&gt;as&lt;br&gt;begin&lt;br&gt;declare @f float&lt;br&gt;set @f = (select random_value from wrapped_rand_view)&lt;br&gt;return @f&lt;br&gt;end&lt;br&gt;&lt;/p&gt;select --your columns--, dbo.wrapped_rand() wrapped_rand&lt;br&gt;from YourTable&lt;br&gt;&lt;img src="http://sqlblogcasts.com/aggbug.aspx?PostID=2442" width="1" height="1"&gt;</content><author><name>Alex_Kuznetsov</name><uri>http://sqlblogcasts.com/members/Alex_5F00_Kuznetsov.aspx</uri></author></entry></feed>