<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DE8GSHg6fip7ImA9WhRRFE4.&quot;"><id>tag:blogger.com,1999:blog-3561617962469253143</id><updated>2011-11-27T15:33:49.616-08:00</updated><category term="C#" /><category term="Linq" /><category term="Sql" /><title>Ryan's coding blog</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://ryancoder.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://ryancoder.blogspot.com/" /><author><name>Ryan Hennig</name><uri>http://www.blogger.com/profile/00825532811928979346</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>2</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/RyansCodingBlog" /><feedburner:info uri="ryanscodingblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;D0ACSX46cSp7ImA9WxFVEk8.&quot;"><id>tag:blogger.com,1999:blog-3561617962469253143.post-3993144030179499670</id><published>2010-06-10T19:45:00.000-07:00</published><updated>2010-06-10T20:09:28.019-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-10T20:09:28.019-07:00</app:edited><title>Bucket DateTimes in T-SQL</title><content type="html">Today at work I was working on a SQL Server Reporting Services report which shows us the number of rows being created in a certain table in each 10-minute interval.  While working on this, I tried several different ways in which I could "bucket" the datetime column into the same ten-minute period.  At the end, I finally decided to extract this logic into a User-Defined Function which can bucket any datetime into any size interval.&lt;br /&gt;&lt;br /&gt;Here's the function:&lt;br /&gt;&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;style type="text/css"&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: Consolas, "Courier New", Courier, Monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;&lt;/style&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;/* BucketDateTime: &lt;br /&gt; * Buckets &lt;span class="kwrd"&gt;any&lt;/span&gt; datetime &lt;span class="kwrd"&gt;into&lt;/span&gt; an &lt;span class="kwrd"&gt;interval&lt;/span&gt; &lt;span class="kwrd"&gt;of&lt;/span&gt; the given &lt;span class="kwrd"&gt;size&lt;/span&gt;. &lt;br /&gt; * &lt;span class="kwrd"&gt;Returns&lt;/span&gt; the minimum datetime &lt;span class="kwrd"&gt;for&lt;/span&gt; the &lt;span class="kwrd"&gt;interval&lt;/span&gt; chosen, &lt;span class="kwrd"&gt;or&lt;/span&gt; &lt;span class="kwrd"&gt;NULL&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; @MinutesPerBucket &amp;lt; 1&lt;br /&gt; * Example: bucket times 7:29pm &lt;span class="kwrd"&gt;and&lt;/span&gt; 7:31pm &lt;span class="kwrd"&gt;to&lt;/span&gt; the nearest 30 &lt;span class="kwrd"&gt;minute&lt;/span&gt; &lt;span class="kwrd"&gt;interval&lt;/span&gt;&lt;br /&gt; * &lt;span class="kwrd"&gt;SELECT&lt;/span&gt; dbo.BucketDateTime(&lt;span class="str"&gt;'2010-04-01 19:29:00'&lt;/span&gt;, 30) =&amp;gt; &lt;span class="str"&gt;'2010-04-01 19:00:00.000'&lt;/span&gt;&lt;br /&gt; * &lt;span class="kwrd"&gt;SELECT&lt;/span&gt; dbo.BucketDateTime(&lt;span class="str"&gt;'2010-04-01 19:31:00'&lt;/span&gt;, 30) =&amp;gt; &lt;span class="str"&gt;'2010-04-01 19:30:00.000'&lt;/span&gt;&lt;br /&gt; */&lt;br /&gt; &lt;span class="kwrd"&gt;CREATE&lt;/span&gt; &lt;span class="kwrd"&gt;FUNCTION&lt;/span&gt; [dbo].[BucketDateTime]&lt;br /&gt;(&lt;br /&gt;    @SourceDateTime DATETIME, &lt;span class="rem"&gt;-- The DateTime to bucket&lt;/span&gt;&lt;br /&gt;    @MinutesPerBucket &lt;span class="kwrd"&gt;INT&lt;/span&gt;     &lt;span class="rem"&gt;-- The number of minutes per bucket.&lt;/span&gt;&lt;br /&gt;)&lt;br /&gt;&lt;span class="kwrd"&gt;RETURNS&lt;/span&gt; DATETIME&lt;br /&gt;&lt;span class="kwrd"&gt;AS&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;BEGIN&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;IF&lt;/span&gt; (@MinutesPerBucket &amp;lt; 1) &lt;span class="kwrd"&gt;RETURN&lt;/span&gt; &lt;span class="kwrd"&gt;NULL&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;    &lt;span class="rem"&gt;-- The earliest possible datetime&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;DECLARE&lt;/span&gt; @Epoch DATETIME                    &lt;br /&gt;    &lt;br /&gt;    &lt;span class="rem"&gt;-- # of minutes passed between the epoch and source datetime&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;DECLARE&lt;/span&gt; @MinutesSinceEpoch &lt;span class="kwrd"&gt;INT&lt;/span&gt;            &lt;br /&gt;    &lt;br /&gt;    &lt;span class="rem"&gt;-- The value to bucket @SourceDateTime into, based on @MinutesPerBucket&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;DECLARE&lt;/span&gt; @BucketDateTime DATETIME        &lt;br /&gt;    &lt;br /&gt;    &lt;span class="rem"&gt;-- # of minutes passed between @BucketDateTime&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;DECLARE&lt;/span&gt; @BucketMinutesSinceEpoch &lt;span class="kwrd"&gt;INT&lt;/span&gt;    &lt;br /&gt;    &lt;br /&gt;    &lt;span class="rem"&gt;-- This value is from Books online: http://msdn.microsoft.com/en-us/library/ms186724.aspx&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;SET&lt;/span&gt; @Epoch = &lt;span class="kwrd"&gt;CAST&lt;/span&gt;(&lt;span class="str"&gt;'1753-01-01'&lt;/span&gt; &lt;span class="kwrd"&gt;AS&lt;/span&gt; DATETIME)     &lt;br /&gt;    &lt;br /&gt;    &lt;span class="kwrd"&gt;SET&lt;/span&gt; @MinutesSinceEpoch = DATEDIFF(mi, @Epoch, @SourceDateTime)&lt;br /&gt;    &lt;br /&gt;    &lt;span class="kwrd"&gt;SET&lt;/span&gt; @BucketMinutesSinceEpoch = @MinutesSinceEpoch - (@MinutesSinceEpoch % @MinutesPerBucket)&lt;br /&gt;    &lt;br /&gt;    &lt;span class="kwrd"&gt;SET&lt;/span&gt; @BucketDateTime = DATEADD(mi, @BucketMinutesSinceEpoch, @Epoch)&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;RETURN&lt;/span&gt; @BucketDateTime&lt;br /&gt;    &lt;br /&gt;&lt;span class="kwrd"&gt;END&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;GO&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3561617962469253143-3993144030179499670?l=ryancoder.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ph0CvX4e2rFerqfgREFNrSd_rxo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ph0CvX4e2rFerqfgREFNrSd_rxo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ph0CvX4e2rFerqfgREFNrSd_rxo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ph0CvX4e2rFerqfgREFNrSd_rxo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/RyansCodingBlog/~4/RlwMJCs6k2g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ryancoder.blogspot.com/feeds/3993144030179499670/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ryancoder.blogspot.com/2010/06/bucket-datetimes-in-t-sql.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3561617962469253143/posts/default/3993144030179499670?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3561617962469253143/posts/default/3993144030179499670?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RyansCodingBlog/~3/RlwMJCs6k2g/bucket-datetimes-in-t-sql.html" title="Bucket DateTimes in T-SQL" /><author><name>Ryan Hennig</name><uri>http://www.blogger.com/profile/00825532811928979346</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://ryancoder.blogspot.com/2010/06/bucket-datetimes-in-t-sql.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUUASHg4fyp7ImA9WxFVEEk.&quot;"><id>tag:blogger.com,1999:blog-3561617962469253143.post-3889711695362823083</id><published>2010-06-08T16:43:00.000-07:00</published><updated>2010-06-08T17:27:29.637-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-08T17:27:29.637-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Sql" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="Linq" /><title>Execute LINQ queries without locking any tables</title><content type="html">At work I'm building an application which queries a SQL Server backend with LINQ to SQL, and I recently found that some of my queries were slow due to table locking.  I found &lt;a href="http://www.infoq.com/news/2008/03/linq-nolock"&gt;this excellent blog post&lt;/a&gt; referencing &lt;a href="http://www.hanselman.com/blog/GettingLINQToSQLAndLINQToEntitiesToUseNOLOCK.aspx"&gt;Scott Hanselman's blog post&lt;/a&gt; which describes how to execute LINQ queries without locking the source tables:&lt;br /&gt;&lt;br /&gt;Deciding to go with option 1, I came up with an elegant solution for easily adding this to any LINQ queries.  Let's say you are using a LINQ query like this:&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;var query = from f &lt;span class="kwrd"&gt;in&lt;/span&gt; Foo&lt;br /&gt;    select &lt;span class="kwrd"&gt;new&lt;/span&gt; { Foo = f };&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var item &lt;span class="kwrd"&gt;in&lt;/span&gt; query)&lt;br /&gt;{&lt;br /&gt;&lt;span class="rem"&gt;    //Do something&lt;/span&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;In this case, the query is actually executed in the foreach loop.  By implementing an extension method, you can easily change this to use a transaction with the "Read Uncommitted" Isolation Level like so:&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;var query = from f &lt;span class="kwrd"&gt;in&lt;/span&gt; Foo&lt;br /&gt;    select &lt;span class="kwrd"&gt;new&lt;/span&gt; { Foo = f };&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var item &lt;span class="kwrd"&gt;in&lt;/span&gt; query.ToListNoLock())&lt;br /&gt;{&lt;br /&gt;&lt;span class="rem"&gt;    //Do something&lt;/span&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;The extension method is implemented like so:&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; IEnumerableExtension&lt;br /&gt;{&lt;br /&gt;   &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; TransactionScope CreateNoLockTransaction()&lt;br /&gt;   {&lt;br /&gt;       var options = &lt;span class="kwrd"&gt;new&lt;/span&gt; TransactionOptions&lt;br /&gt;       {&lt;br /&gt;           IsolationLevel = IsolationLevel.ReadUncommitted&lt;br /&gt;       };&lt;br /&gt;       &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; TransactionScope(TransactionScopeOption.Required, options);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; List&amp;lt;T&amp;gt; ToListNoLock&amp;lt;T&amp;gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt; IEnumerable&amp;lt;T&amp;gt; query)&lt;br /&gt;   {&lt;br /&gt;       &lt;span class="kwrd"&gt;using&lt;/span&gt; (TransactionScope ts = CreateNoLockTransaction())&lt;br /&gt;       {&lt;br /&gt;           &lt;span class="kwrd"&gt;return&lt;/span&gt; query.ToList();&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And then of course you can implement new versions of various other extension methods on IEnumerable/IQueryable, such as SingleOrDefault, FirstOrDefault, etc.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Note that this is the same as adding (NOLOCK) hints to EVERY table in your query.  I do not currently know of a way to add nolock hints to individual tables.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3561617962469253143-3889711695362823083?l=ryancoder.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/waS4OO5swGLcheNDYeR2ZH4yttc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/waS4OO5swGLcheNDYeR2ZH4yttc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/waS4OO5swGLcheNDYeR2ZH4yttc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/waS4OO5swGLcheNDYeR2ZH4yttc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/RyansCodingBlog/~4/G1mOtWI9WTU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ryancoder.blogspot.com/feeds/3889711695362823083/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ryancoder.blogspot.com/2010/06/execute-linq-queries-without-locking.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3561617962469253143/posts/default/3889711695362823083?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3561617962469253143/posts/default/3889711695362823083?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RyansCodingBlog/~3/G1mOtWI9WTU/execute-linq-queries-without-locking.html" title="Execute LINQ queries without locking any tables" /><author><name>Ryan Hennig</name><uri>http://www.blogger.com/profile/00825532811928979346</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://ryancoder.blogspot.com/2010/06/execute-linq-queries-without-locking.html</feedburner:origLink></entry></feed>

