<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.technet.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title> Mat Stephen's SQL Server WebLog : T-SQL</title><link>http://blogs.technet.com/mat_stephen/archive/tags/T-SQL/default.aspx</link><description>Tags: T-SQL</description><dc:language>en-GB</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Getting to know SQL 2005 Service Broker</title><link>http://blogs.technet.com/mat_stephen/archive/2005/09/12/ServiceBroker.aspx</link><pubDate>Tue, 13 Sep 2005 00:27:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:410667</guid><dc:creator>Mat_Stephen</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.technet.com/mat_stephen/comments/410667.aspx</comments><wfw:commentRss>http://blogs.technet.com/mat_stephen/commentrss.aspx?PostID=410667</wfw:commentRss><description>&lt;P&gt;Looks likes I've got to do&amp;nbsp;a presentation on Service Broker for the SQL 2005 launch - so I've been doing some home work on the subject.&lt;/P&gt;
&lt;P&gt;The best primer I've found is &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsql90/html/sqlsvcbroker.asp?frame=true"&gt;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsql90/html/sqlsvcbroker.asp?frame=true&lt;/A&gt;&amp;nbsp;this is refernenced in the webcast &lt;A href="http://msevents.microsoft.com/cui/WebCastEventDetails.aspx?EventID=1032263311&amp;amp;EventCategory=5&amp;amp;culture=en-us&amp;amp;CountryCode=US"&gt;http://msevents.microsoft.com/cui/WebCastEventDetails.aspx?EventID=1032263311&amp;amp;EventCategory=5&amp;amp;culture=en-us&amp;amp;CountryCode=US&lt;/A&gt;.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Once you've got your head round the basics you'll want to create your ow broker service and queues.&amp;nbsp; Best I've found is "Setting Up a Service Broker Service and Queue" from SQL Server 2005 Books on line at ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/smo9/html/f6f1c8b5-393b-48f2-a2b0-184fef683b5c.htm.&amp;nbsp; Problem with this is there's a bug in the code.&amp;nbsp; I can't remember the delta between what's printed and what I have working, but my suggestion is to use the code below to create the TargetStoredProcedure and then comment out the sp.Create(); line in the sample code with //.&lt;/P&gt;
&lt;P&gt;Hope you enjoy this new technology - if I discover some new usefulties (a new word I've just invented) in this area, I'll post them in my new 'Service Broker' category&lt;/P&gt;
&lt;P&gt;USE [AdventureWorks]&lt;BR&gt;GO&lt;BR&gt;/****** Object:&amp;nbsp; StoredProcedure [dbo].[TargetStoredProcedure]&amp;nbsp;&amp;nbsp;&amp;nbsp; Script Date: 09/12/2005 23:17:28 ******/&lt;BR&gt;SET ANSI_NULLS ON&lt;BR&gt;GO&lt;BR&gt;SET QUOTED_IDENTIFIER ON&lt;BR&gt;GO&lt;BR&gt;create procedure dbo.TargetStoredProcedure as&lt;BR&gt;DECLARE @message_body varbinary(MAX); &lt;BR&gt;DECLARE @message_type_name nvarchar(128); &lt;BR&gt;DECLARE @conversation_handle uniqueidentifier; &lt;BR&gt;DECLARE @message_iduniqueidentifier uniqueidentifier; &lt;BR&gt;DECLARE @message nvarchar(max); &lt;BR&gt;DECLARE @MessageType nvarchar(max); &lt;BR&gt;Declare @message_id nvarchar(max); &lt;/P&gt;
&lt;P&gt;WHILE (1 = 1) &lt;BR&gt;BEGIN &lt;BR&gt;BEGIN TRY &lt;BR&gt;BEGIN TRANSACTION; &lt;BR&gt;WAITFOR ( &lt;/P&gt;
&lt;P&gt;RECEIVE top(1) &lt;BR&gt;@message_type_name = message_type_name, &lt;BR&gt;@message = message_body, &lt;BR&gt;@conversation_handle = conversation_handle, &lt;BR&gt;@message_id = message_id &lt;/P&gt;
&lt;P&gt;FROM TargetQueue &lt;BR&gt;), TIMEOUT 500 &lt;/P&gt;
&lt;P&gt;IF (@@ROWCOUNT = 0) &lt;BR&gt;BEGIN &lt;BR&gt;ROLLBACK TRANSACTION &lt;BR&gt;BREAK &lt;BR&gt;END; &lt;BR&gt;select @message = N'&amp;lt;Hello&amp;gt;Pong&amp;lt;/Hello&amp;gt;'; &lt;BR&gt;set @MessageType = '//microsoft.com/ssbdemo/PongMessageType'; &lt;BR&gt;SEND ON CONVERSATION @conversation_handle &lt;BR&gt;MESSAGE TYPE @MessageType &lt;BR&gt;(@message); &lt;BR&gt;END CONVERSATION @conversation_handle &lt;BR&gt;COMMIT TRANSACTION &lt;BR&gt;END TRY &lt;BR&gt;BEGIN CATCH &lt;BR&gt;print @@error; &lt;BR&gt;ROLLBACK &lt;BR&gt;CONTINUE &lt;BR&gt;END CATCH &lt;BR&gt;END; &lt;BR&gt;GO&lt;BR&gt;SET ANSI_NULLS OFF&lt;BR&gt;GO&lt;BR&gt;SET QUOTED_IDENTIFIER OFF&lt;/P&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=410667" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/mat_stephen/archive/tags/Performance/default.aspx">Performance</category><category domain="http://blogs.technet.com/mat_stephen/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category><category domain="http://blogs.technet.com/mat_stephen/archive/tags/Webcasts/default.aspx">Webcasts</category><category domain="http://blogs.technet.com/mat_stephen/archive/tags/T-SQL/default.aspx">T-SQL</category><category domain="http://blogs.technet.com/mat_stephen/archive/tags/Architects+Corner/default.aspx">Architects Corner</category><category domain="http://blogs.technet.com/mat_stephen/archive/tags/Service+Broker/default.aspx">Service Broker</category></item><item><title>SQL 2005: Making sense of the new Optimistic Concurrency Controls and the readers that block writers</title><link>http://blogs.technet.com/mat_stephen/archive/2005/09/06/Concurrency-.aspx</link><pubDate>Tue, 06 Sep 2005 20:11:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:410349</guid><dc:creator>Mat_Stephen</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.technet.com/mat_stephen/comments/410349.aspx</comments><wfw:commentRss>http://blogs.technet.com/mat_stephen/commentrss.aspx?PostID=410349</wfw:commentRss><description>&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;For a long time now Oracle enthusiasts have bashed SQL Server for not having Optimistic Concurrency Controls.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;They would demonstrate a SQL Server reader blocking a writer and possibly a writer blocking a reader.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Thus, having appeared to demonstrate that SQL can&lt;?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /&gt;&lt;st1:PersonName w:st="on"&gt;'&lt;/st1:PersonName&gt;t handle these two operations concurrently, they would therefore conclude that SQL can&lt;st1:PersonName w:st="on"&gt;'&lt;/st1:PersonName&gt;t scale - certainly not to enterprise level workloads; workloads that involve lots of people writing to a database at the same time as lots of people wanting to read from it.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;This, of course, is a rather dirty trick; you only have to look at http://www.microsoft.com/sql/evaluation/compare/benchmarks.mspx to see SQL Server 2000 performance against various typical 3rd party LOB application workloads that involve reading and writing.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;So how did/do they perform these mischievous tricks - here&lt;st1:PersonName w:st="on"&gt;'&lt;/st1:PersonName&gt;s how:&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;Open connection 1&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;USE AdventureWorks&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;GO&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;BEGIN TRANSACTION&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-tab-count: 1"&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;UPDATE Production.Product&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-tab-count: 1"&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;SET StandardCost = 5.0,&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-tab-count: 2"&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ListPrice = 11.50&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-tab-count: 1"&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;WHERE Name LIKE &lt;st1:PersonName w:st="on"&gt;'&lt;/st1:PersonName&gt;%sock%&lt;st1:PersonName w:st="on"&gt;'&lt;/st1:PersonName&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;Open connection 2&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;USE AdventureWorks&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;GO&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-tab-count: 1"&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;SELECT&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Name,&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-tab-count: 2"&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;StandardCost,&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-tab-count: 2"&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ListPrice&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-tab-count: 1"&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;FROM Production.Product&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-tab-count: 1"&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;WHERE Name LIKE &lt;st1:PersonName w:st="on"&gt;'&lt;/st1:PersonName&gt;%Sock%&lt;st1:PersonName w:st="on"&gt;'&lt;/st1:PersonName&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;You will now see that connection 2 will not return anything - instead it just sits there doing nothing.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Here the writer on connection 1 blocks the reader on connection 2.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This blocking will continue until connection 1 either commits or rollbacks the transaction it started with BEGIN TRANSACTION.&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;Well it would be very easy, at this stage, to get into a religious slanging match - and you know I don&lt;st1:PersonName w:st="on"&gt;'&lt;/st1:PersonName&gt;t do religion very easily.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Luckily, with SQL 2005, I don&lt;st1:PersonName w:st="on"&gt;'&lt;/st1:PersonName&gt;t even have to think about get religious about this situation, because SQL Server 2005 now supports the necessary isolation levels to stop this happening.&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;At this point I&lt;st1:PersonName w:st="on"&gt;'&lt;/st1:PersonName&gt;m reminded of an old joke told by Tommy Cooper:&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Bloke goes to see a Doctor, he lifts his arm in the air and says, "Doctor, every time I do this it hurts."&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;And the Doctor says, "Well don&lt;st1:PersonName w:st="on"&gt;'&lt;/st1:PersonName&gt;t do it then."&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;I&lt;st1:PersonName w:st="on"&gt;'&lt;/st1:PersonName&gt;m reminded of this joke because if you begin a transaction, update a value and then you find it causes other people problems - I would suggest you don&lt;st1:PersonName w:st="on"&gt;'&lt;/st1:PersonName&gt;t do it.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Why begin a transaction, do some work and then walk off without committing it?&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;Okay - so you might have a &lt;st1:PersonName w:st="on"&gt;'&lt;/st1:PersonName&gt;really big update&lt;st1:PersonName w:st="on"&gt;'&lt;/st1:PersonName&gt; that takes ages to run and it can&lt;st1:PersonName w:st="on"&gt;'&lt;/st1:PersonName&gt;t be batched up into smaller transactions and you need to run some very long running reports that have to have a transactionally consistant view of the data.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Indeed; you might also be very unlucky and get struck by lightening!&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;In SQL 2000 there are various ways to obviate the encumbrance of this &lt;st1:PersonName w:st="on"&gt;'&lt;/st1:PersonName&gt;really big update&lt;st1:PersonName w:st="on"&gt;'&lt;/st1:PersonName&gt; and nasty report – but I don&lt;st1:PersonName w:st="on"&gt;'&lt;/st1:PersonName&gt;t want to go down that road, like I said I want to avoid a religious debate.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Now, in SQL 2005, we have exactly the same capability as Oracle to make such an operation very easy for the developer.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Like Oracle, this capability employs the concept of &lt;st1:PersonName w:st="on"&gt;'&lt;/st1:PersonName&gt;versioning&lt;st1:PersonName w:st="on"&gt;'&lt;/st1:PersonName&gt;, which means each connection in the above scenario will work with its own version of the data, thus avoiding contention.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;However as with Oracle, versioning takes up both processing and i/o at the server, resources that are potentially very expensive and not to be wasted if you don&lt;st1:PersonName w:st="on"&gt;'&lt;/st1:PersonName&gt;t have to.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Does Oracle do any benchmarks with this feature turned on? &lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;I don&lt;st1:PersonName w:st="on"&gt;'&lt;/st1:PersonName&gt;t think so, and nor would SQL for that matter.&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;I will argue that versioning is frequently used as a way to make developers jobs easier and not because it’s actually necessary.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;By that I also mean it makes it easier for developers to write sloppy code - and by that you can happily infer I believe it makes it easier to employ cheaper developers.&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;So how do we go about &lt;S&gt;employing these cheaper developers&lt;/S&gt;, sorry, reducing contention on the database?&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;To do this we now have two new isolation levels:&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;1. SNAPSHOT ISOLATION (Transaction-level Snapshot)&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 36pt"&gt;Administrators must set the new ALLOW_SNAPSHOT_ISOLATION&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;database option to allow Snapshot Isolation.&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 36pt"&gt;In order to start a transaction that uses Snapshot Isolation a developer must SET TRANSACTION ISOLATION LEVEL SNAPSHOT&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 36pt"&gt;RESULT: Every statement within a Snapshot Isolation Transaction sees the same version of data comprised only of committed changes which occurred before the start &lt;SPAN style="mso-tab-count: 2"&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; &lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 36pt"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 36pt"&gt;of the transaction.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Other statements inside other transactions do not see the changes made inside this Snapshot Isolation Transaction.&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;2. READ COMMITTED WITH SNAPSHOT ISOLATION (Statement-level Snapshot)&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 36pt"&gt;Administrators must set the new READ_COMMITTED_SNAPSHOT database option to allow Read Committed Snapshot Isolation&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 36pt"&gt;No further application level changes are required to have statements use Read-Committed Isolation.&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 36pt"&gt;RESULT: Each statement sees a version of the data that was committed just before the statement began, instead of when the resource is read.&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp; &lt;/SPAN&gt;This is merely a new implementation of read committed that is non-locking and non-blocking; the data is accurate only as at the start of the statement. &lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=410349" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/mat_stephen/archive/tags/Business+Intelligence/default.aspx">Business Intelligence</category><category domain="http://blogs.technet.com/mat_stephen/archive/tags/High+Availability+and+Disaster+Recovery/default.aspx">High Availability and Disaster Recovery</category><category domain="http://blogs.technet.com/mat_stephen/archive/tags/Performance/default.aspx">Performance</category><category domain="http://blogs.technet.com/mat_stephen/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category><category domain="http://blogs.technet.com/mat_stephen/archive/tags/T-SQL/default.aspx">T-SQL</category></item><item><title>SQL 2005 - UPSERT: In nature but not by name; but at last!</title><link>http://blogs.technet.com/mat_stephen/archive/2005/08/31/410022.aspx</link><pubDate>Wed, 31 Aug 2005 12:34:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:410022</guid><dc:creator>Mat_Stephen</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.technet.com/mat_stephen/comments/410022.aspx</comments><wfw:commentRss>http://blogs.technet.com/mat_stephen/commentrss.aspx?PostID=410022</wfw:commentRss><description>&lt;P&gt;SQL Server has long been &lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman'; mso-ansi-language: EN-GB; mso-fareast-font-family: 'Times New Roman'; mso-fareast-language: EN-GB; mso-bidi-language: AR-SA"&gt;criticised for not having an UPSERT command, well now in SQL 2005 we have some good news, we have two new TSQL set operators that give us the complex insert/update logic that constitute an UPSERT.&amp;nbsp; These are INTERSECT and EXCEPT&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman'; mso-ansi-language: EN-GB; mso-fareast-font-family: 'Times New Roman'; mso-fareast-language: EN-GB; mso-bidi-language: AR-SA"&gt;e.g.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman'; mso-ansi-language: EN-GB; mso-fareast-font-family: 'Times New Roman'; mso-fareast-language: EN-GB; mso-bidi-language: AR-SA"&gt;-- UPDATE Destination FROM (Source INTERSECT Destination)&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman'; mso-ansi-language: EN-GB; mso-fareast-font-family: 'Times New Roman'; mso-fareast-language: EN-GB; mso-bidi-language: AR-SA"&gt;-- INSERT INTO Destination FROM (Source EXCEPT Destination)&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman'; mso-ansi-language: EN-GB; mso-fareast-font-family: 'Times New Roman'; mso-fareast-language: EN-GB; mso-bidi-language: AR-SA"&gt;These statements obviate the need to construct complex correlated sub-queries or WHERE EXISTS logic.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman'; mso-ansi-language: EN-GB; mso-fareast-font-family: 'Times New Roman'; mso-fareast-language: EN-GB; mso-bidi-language: AR-SA"&gt;And what's more, these operators deliver high performance by exposing core engine functions.&lt;/SPAN&gt;&lt;/P&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=410022" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/mat_stephen/archive/tags/Performance/default.aspx">Performance</category><category domain="http://blogs.technet.com/mat_stephen/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category><category domain="http://blogs.technet.com/mat_stephen/archive/tags/Performance+Top+Tips/default.aspx">Performance Top Tips</category><category domain="http://blogs.technet.com/mat_stephen/archive/tags/T-SQL/default.aspx">T-SQL</category></item><item><title>Are you still using @@IDENTITY?  </title><link>http://blogs.technet.com/mat_stephen/archive/2005/07/19/SCOPE-IDENTITY.aspx</link><pubDate>Tue, 19 Jul 2005 11:50:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:407868</guid><dc:creator>Mat_Stephen</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.technet.com/mat_stephen/comments/407868.aspx</comments><wfw:commentRss>http://blogs.technet.com/mat_stephen/commentrss.aspx?PostID=407868</wfw:commentRss><description>&lt;P&gt;Are you still using @@IDENTITY?&amp;nbsp; It seems many people are.&amp;nbsp; If you are, are you aware that it might not always return what you expect?&amp;nbsp; No? then read on. &amp;nbsp;@@IDENTITY will return the last IDENTITY column value inserted across any scope in the current session.&amp;nbsp; This means that if a trigger, or similar,&amp;nbsp;were to insert a row in another table (T2), other than the one you're interested in (T1),&amp;nbsp;inside the same transaction and after you insert into T1, you will get the Identity value of T2 instead of T1.&lt;/P&gt;
&lt;P&gt;SCOPE_IDENTITY returns values inserted only within the current scope and obviates this problem.&amp;nbsp; You may also be interested in IDENT_CURRENT as this&amp;nbsp;is not limited by scope and session; it is limited to a specified table.&lt;/P&gt;
&lt;P&gt;For more info and an example, check these functions&amp;nbsp;out in Books On Line.&lt;/P&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=407868" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/mat_stephen/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category><category domain="http://blogs.technet.com/mat_stephen/archive/tags/SQL+Server+2000/default.aspx">SQL Server 2000</category><category domain="http://blogs.technet.com/mat_stephen/archive/tags/T-SQL/default.aspx">T-SQL</category></item><item><title>Cool new OVER Clause (Transact-SQL) in SQL Server 2005</title><link>http://blogs.technet.com/mat_stephen/archive/2005/06/23/406768.aspx</link><pubDate>Thu, 23 Jun 2005 18:40:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:406768</guid><dc:creator>Mat_Stephen</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.technet.com/mat_stephen/comments/406768.aspx</comments><wfw:commentRss>http://blogs.technet.com/mat_stephen/commentrss.aspx?PostID=406768</wfw:commentRss><description>&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=3&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;Cool new OVER Clause (Transact-SQL) in SQL Server 2005 to circumvent the not so efficient correlated subquery.&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=3&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;Imagine a table:&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=3&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;create table grades(&lt;BR&gt;&amp;nbsp;StudentID int not null&lt;BR&gt;,StudentName varchar(10) not null&lt;BR&gt;,Subject varchar(10) not null&lt;BR&gt;,Score&amp;nbsp; int not null)&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=3&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;With some values:&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=3&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;insert into grades values(1,'John','Math',87)&lt;BR&gt;insert into grades values(1,'John','Geography',76)&lt;BR&gt;insert into grades values(1,'John','History',98)&lt;BR&gt;insert into grades values(1,'John','Science',85)&lt;BR&gt;insert into grades values(2,'Sally','Crafts',89)&lt;BR&gt;insert into grades values(2,'Sally','Science',88)&lt;BR&gt;insert into grades values(2,'Sally','History',76)&lt;BR&gt;insert into grades values(3,'Molly','English',87)&lt;BR&gt;insert into grades values(3,'Molly','Science',76)&lt;BR&gt;insert into grades values(3,'Molly','Geography',83)&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=3&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;You want to return each student with their highest two scoring subjects e.g.&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=3&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;John&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;History&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;98&lt;BR&gt;John&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Math&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;87&lt;BR&gt;Sally&amp;nbsp;&amp;nbsp;&amp;nbsp;Crafts&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;89&lt;BR&gt;Sally&amp;nbsp;&amp;nbsp;&amp;nbsp;Science&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;88&lt;BR&gt;Molly&amp;nbsp;&amp;nbsp;&amp;nbsp;English&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;87&lt;BR&gt;Molly&amp;nbsp;&amp;nbsp;&amp;nbsp;Geography&amp;nbsp;&amp;nbsp;83&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=3&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;In SQL 2000 you may have used a correlated subquery thus:&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=3&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;select studentname, subject, score &lt;BR&gt;from grades o&lt;BR&gt;where score in (select top 2 score from grades i where i.studentname = o.studentname order by score desc)&lt;BR&gt;order by studentname,score desc&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=3&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;However much more efficient and simpler in SQL 2005 is the new OVER clause: &lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=3&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;select studentname, subject, score&lt;BR&gt;from&lt;BR&gt;(&lt;BR&gt;&amp;nbsp;&amp;nbsp; select studentname, subject, score, &lt;BR&gt;&amp;nbsp;&amp;nbsp; row_number() over (partition by studentid order by score desc) as rownum&lt;BR&gt;&amp;nbsp;&amp;nbsp; from grades&amp;nbsp; &lt;BR&gt;) dt&lt;BR&gt;where rownum&amp;lt;=2&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=3&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;The OVER clause: Determines the partitioning and ordering of the rowset before the associated window function is applied.&amp;nbsp; Applies to: Ranking Window functions&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=3&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;Very cool me thinks.&amp;nbsp; My thanks to David Browne and Alfredo Ramirez for bringing this to my attention.&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=406768" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/mat_stephen/archive/tags/Performance/default.aspx">Performance</category><category domain="http://blogs.technet.com/mat_stephen/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category><category domain="http://blogs.technet.com/mat_stephen/archive/tags/T-SQL/default.aspx">T-SQL</category></item></channel></rss>