<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Database</title>
        <link>http://www.ridgway.co.za/category/12.aspx</link>
        <description>Database</description>
        <language>en-ZA</language>
        <copyright>Eden Ridgway</copyright>
        <managingEditor>eden@ridgway.co.za</managingEditor>
        <generator>Subtext Version 1.9.5.176</generator>
        <item>
            <title>.Net Developer's Guide to Getting Started with Cassandra</title>
            <link>http://ridgway.co.za/archive/2009/11/06/net-developers-guide-to-getting-started-with-cassandra.aspx</link>
            <description>&lt;p&gt;I've been quite curious about the various &lt;a href="http://en.wikipedia.org/wiki/BigTable" target="_blank"&gt;BigTable&lt;/a&gt; like implementations as they could have some bearing on what I am involved with at work. After reading various write ups about the competing approaches (e.g. &lt;a href="http://www.vimeo.com/5198661" target="_blank"&gt;HyperTable&lt;/a&gt;, HBase, Dynomite, Voldemort, &lt;a href="http://www.vimeo.com/5184456" target="_blank"&gt;Mongodb&lt;/a&gt;) I decided that &lt;a href="http://incubator.apache.org/cassandra/" target="_blank"&gt;Cassandra&lt;/a&gt; looked like the best option for what I'm after. What I didn't realise was that it wasn't going to be as straight forward as it appears to set it all up as there is no end-to-end guide of getting started with it. So the objective of this post is not to explain Cassandra but save you several hours of jumping all over the web trying to work out what you should do next and how to generate the necessary C# Cassandra Thrift client code. If parts of the post don't apply, e.g. VM setup, simply skip ahead to the parts that do. If you want more information about Cassandra you should check out the following posts: &lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://blog.evanweaver.com/articles/2009/07/06/up-and-running-with-cassandra/" target="_blank"&gt;Up and running with Cassandra&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://arin.me/code/wtf-is-a-supercolumn-cassandra-data-model" target="_blank"&gt;WTF is a SuperColumn? An Intro to the Cassandra Data Model&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;So to get Cassandra up and running in a Virtual Machine (or physical if you choose) you should follow the following steps (valid as at 5 Nov 2010):&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;Create a virtual machine to host &lt;a href="http://www.ubuntu.com/getubuntu/download" target="_blank"&gt;Ubuntu 9.10 x86 Desktop&lt;/a&gt;. I use &lt;a href="http://www.virtualbox.org/" target="_blank"&gt;VirtualBox&lt;/a&gt; as my VM host on windows so I will refer to this here but feel free to substitute it with you favourite VM software. The VM I created has 384MB allocated to it with an 8GB virtual hard drive using a bridged network adapter (so it can be accessed from the Windows XP host). Once you've gone through the install process install the client tools so that you change the screen resolution, share folders, etc. To do this with virtual box go to &lt;strong&gt;Devices &amp;gt; Install Guest Additions&lt;/strong&gt; and then open up a terminal window and execute       &lt;br /&gt;
    &lt;br /&gt;
    &lt;div style="background: black none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: white;"&gt;&lt;span style="color: rgb(0, 128, 255);"&gt;sudo&lt;/span&gt; /media/cdrom/VBoxLinuxAdditions-x86.run&lt;/div&gt;
    &lt;br /&gt;
    Once this is complete you will need to reboot your VM.       &lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;Now it is time to install Cassandra/Thrift prerequisites and software that we will to set everything up:      &lt;br /&gt;
    &lt;br /&gt;
    &lt;div style="background: black none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: white;"&gt;&lt;span style="color: rgb(0, 128, 255);"&gt;sudo&lt;/span&gt; apt-get install libboost-dev automake libtool flex bison pkg-config g++ -y         &lt;br /&gt;
    &lt;span style="color: rgb(0, 128, 255);"&gt;sudo&lt;/span&gt; apt-get install sun-java6-jdk -y         &lt;br /&gt;
    &lt;span style="color: rgb(0, 128, 255);"&gt;sudo&lt;/span&gt; apt-get apt-get install ant -y         &lt;br /&gt;
    &lt;/div&gt;
    &lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;Once that is done we can install other useful Ubuntu software that we will use:      &lt;br /&gt;
    &lt;br /&gt;
    &lt;div style="background: black none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: white;"&gt;&lt;span style="color: rgb(0, 128, 255);"&gt;sudo&lt;/span&gt; apt-get install rapidsvn -y         &lt;br /&gt;
    &lt;span style="color: rgb(0, 128, 255);"&gt;sudo&lt;/span&gt; apt-get install monodevelop -y &lt;/div&gt;
    &lt;br /&gt;
    I also like to install the following:       &lt;br /&gt;
    &lt;br /&gt;
    &lt;div style="background: black none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: white;"&gt;&lt;span style="color: rgb(0, 128, 255);"&gt;sudo&lt;/span&gt; apt-get install nautilus-open-terminal -y         &lt;br /&gt;
    &lt;span style="color: rgb(0, 128, 255);"&gt;sudo&lt;/span&gt; apt-get install samba smbfs smbclient winbind -y         &lt;br /&gt;
    &lt;span style="color: rgb(0, 128, 255);"&gt;sudo&lt;/span&gt; apt-get install nautilus-share -y&lt;/div&gt;
    &lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;You may discover that there is an issue with your Java runtime home directory. If that occurs, select Sun's Java Runtime as the default Java version by running the following command from the terminal window and selecting the third option:      &lt;br /&gt;
    &lt;br /&gt;
    &lt;div style="background: black none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: white;"&gt;&lt;span style="color: rgb(0, 128, 255);"&gt;sudo&lt;/span&gt; update-alternatives --config java &lt;/div&gt;
    &lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;Now open up Nautilus by going to &lt;strong&gt;Places &amp;gt; Home&lt;/strong&gt; Folder. Right click and create a Development folder. Within the Development folder create another two folders: Cassandra and Thrift. &lt;/li&gt;
    &lt;li&gt;We can now get the source for Cassandra and Thrift. Run RapidSVN by going to &lt;strong&gt;Applications &amp;gt; Programming &amp;gt; RapidSVN&lt;/strong&gt;. Check out the source from SVN by going to the RapidSVN menu option &lt;strong&gt;Repository &amp;gt; Checkout&lt;/strong&gt;. In the URL enter &lt;a href="http://svn.apache.org/repos/asf/incubator/thrift/trunk" target="_blank"&gt;http://svn.apache.org/repos/asf/incubator/thrift/trunk&lt;/a&gt; and for the Destination Directory browse to the Thrift development folder. So it should look like this:       &lt;br /&gt;
    &lt;br /&gt;
    &lt;a href="http://www.ridgway.co.za/images/ridgway_co_za/WindowsLiveWriter/8fe.NetDevelopersGuidetoGettingStartedwi_4F37/image_4.png"&gt;&lt;img border="0" width="244" height="126" style="border-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto;" title="image" alt="image" src="http://www.ridgway.co.za/images/ridgway_co_za/WindowsLiveWriter/8fe.NetDevelopersGuidetoGettingStartedwi_4F37/image_thumb_1.png" /&gt;&lt;/a&gt;       &lt;br /&gt;
    Now get the Cassandra code by doing the same thing but entering &lt;a href="http://svn.apache.org/repos/asf/incubator/cassandra/trunk" target="_blank"&gt;http://svn.apache.org/repos/asf/incubator/cassandra/trunk&lt;/a&gt; as the URL and selecting the Cassandra directory. &lt;/li&gt;
    &lt;li&gt;Once we have all the code we are ready to compile Cassandra, so let's do that by executing the following commands from the terminal window:      &lt;br /&gt;
    &lt;br /&gt;
    &lt;div style="background: black none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: white;"&gt;&lt;span style="color: rgb(0, 128, 255);"&gt;cd&lt;/span&gt; ~/Development/Cassandra         &lt;br /&gt;
    ant         &lt;br /&gt;
    &lt;/div&gt;
    &lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;Start the Cassandra server by opening a new terminal window and running the following commands:      &lt;br /&gt;
    &lt;br /&gt;
    &lt;div style="background: black none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: white;"&gt;&lt;span style="color: rgb(0, 128, 255);"&gt;sudo&lt;/span&gt; ~/Development/Cassandra/bin/cassandra -f         &lt;br /&gt;
    &lt;/div&gt;
    &lt;br /&gt;
    The running server will look like the screenshot below. You should take note of the thrift binding address of localhost/127.0.0.1:9160.       &lt;br /&gt;
    &lt;br /&gt;
    &lt;a href="http://ridgway.co.za/images/ridgway_co_za/WindowsLiveWriter/8fe.NetDevelopersGuidetoGettingStartedwi_4F37/image_5.png"&gt;&lt;img border="0" width="367" height="218" style="border-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto;" title="image" alt="image" src="http://www.ridgway.co.za/images/ridgway_co_za/WindowsLiveWriter/8fe.NetDevelopersGuidetoGettingStartedwi_4F37/image_thumb.png" /&gt;&lt;/a&gt;       &lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;Now we want to get communicating with the server, so we will need to compile Thrift so that we can use it to generate our C# client:      &lt;br /&gt;
    &lt;br /&gt;
    &lt;div style="background: black none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: white;"&gt;&lt;span style="color: rgb(0, 128, 255);"&gt;cd&lt;/span&gt; ~/Development/Thrift         &lt;br /&gt;
    ./bootstrap.sh         &lt;br /&gt;
    ./configure         &lt;br /&gt;
    make         &lt;br /&gt;
    sudo make install         &lt;br /&gt;
    &lt;/div&gt;
    &lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;Now we can finally generate a C# client for the Thrift calls to Cassandra:      &lt;br /&gt;
    &lt;br /&gt;
    &lt;div style="background: black none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: white;"&gt;&lt;span style="color: rgb(0, 128, 255);"&gt;cd&lt;/span&gt; ~/Development/Cassandra/interface/         &lt;br /&gt;
    ~/Development/Thrift/compiler/cpp/thrift -gen csharp cassandra.thrift         &lt;br /&gt;
    &lt;/div&gt;
    &lt;br /&gt;
    This will create the following directories inside of the Cassandra/interface folder: &lt;strong&gt;gen-csharp/Apache/Cassandra&lt;/strong&gt;. These files along with the Thrift.dll will be copied into a new demo project we will create using MonoDevelop in the Development folder. So again in the terminal window execute:       &lt;br /&gt;
    &lt;br /&gt;
    &lt;div style="background: black none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: white;"&gt;&lt;span style="color: rgb(0, 128, 255);"&gt;mkdir&lt;/span&gt; ~/Development/CassandraDemo         &lt;br /&gt;
    &lt;span style="color: rgb(0, 128, 255);"&gt;cp &lt;/span&gt;~/Development/Cassandra/interface/gen-csharp ~/Development/CassandraDemo -R         &lt;br /&gt;
    &lt;span style="color: rgb(0, 128, 255);"&gt;cp &lt;/span&gt;~/Development/Thrift/lib/csharp/Thrift.dll ~/Development/CassandraDemo         &lt;br /&gt;
    &lt;/div&gt;
    &lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;Open up MonoDevelop and create a new console application by going to &lt;strong&gt;File &amp;gt; New &amp;gt; Solution&lt;/strong&gt;. Now do the following:
    &lt;ol&gt;
        &lt;li&gt;Select Console project &lt;/li&gt;
        &lt;li&gt;Enter CassandraDemo as the name &lt;/li&gt;
        &lt;li&gt;For the location browse to the Development folder that we created in your home directory. &lt;/li&gt;
        &lt;li&gt;Uncheck the 'Create separate Solution directory' check box. &lt;/li&gt;
        &lt;li&gt;Click the Forward button &lt;/li&gt;
        &lt;li&gt;Don't make any changes on the next screen and just click Ok. &lt;/li&gt;
        &lt;li&gt;Right click on the CassandraDemo project in the left tree view and select &lt;strong&gt;Add &amp;gt; Add Files...&lt;/strong&gt;. Navigate to ~/Development/CassandraDemo/gen-csharp/Apache/Cassandra and select all the files in the folder. You will now have a project that looks like this:         &lt;br /&gt;
        &lt;br /&gt;
        &lt;a href="http://ridgway.co.za/images/ridgway_co_za/WindowsLiveWriter/8fe.NetDevelopersGuidetoGettingStartedwi_4F37/image_7.png"&gt;&lt;img border="0" width="186" height="264" style="border-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto;" title="image" alt="image" src="http://www.ridgway.co.za/images/ridgway_co_za/WindowsLiveWriter/8fe.NetDevelopersGuidetoGettingStartedwi_4F37/image_thumb_2.png" /&gt;&lt;/a&gt; &lt;/li&gt;
        &lt;li&gt;Add a reference to the Thrift assembly by right clicking on References and selecting Edit References. Change to the .Net Assembly tab and double click on the Thrift.dll and click OK. &lt;/li&gt;
        &lt;li&gt;Now we can add the sample code to test it all out. So double click on Main.cs to ensure that is the class in focus in the editor. Replace the contents of the file with this:        &lt;br /&gt;
        &lt;div class="code"&gt;&lt;font color="#0000ff"&gt;namespace &lt;/font&gt;&lt;font color="#000000"&gt;CassandraDemo           &lt;br /&gt;
        {            &lt;br /&gt;
            &lt;/font&gt;&lt;font color="#0000ff"&gt;using &lt;/font&gt;&lt;font color="#000000"&gt;System&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
            using &lt;/font&gt;&lt;font color="#000000"&gt;System.Collections.Generic&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
            using &lt;/font&gt;&lt;font color="#000000"&gt;System.Diagnostics&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
        &lt;br /&gt;
            using &lt;/font&gt;&lt;font color="#000000"&gt;Apache.Cassandra&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
            using &lt;/font&gt;&lt;font color="#000000"&gt;Thrift.Protocol&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
            using &lt;/font&gt;&lt;font color="#000000"&gt;Thrift.Transport&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
        &lt;br /&gt;
            class &lt;/font&gt;&lt;font color="#000000"&gt;Program           &lt;br /&gt;
            {            &lt;br /&gt;
                &lt;/font&gt;&lt;font color="#0000ff"&gt;static void &lt;/font&gt;&lt;font color="#000000"&gt;Main(&lt;/font&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;font color="#000000"&gt;[] args)           &lt;br /&gt;
                {            &lt;br /&gt;
                    TTransport transport &lt;/font&gt;&lt;font color="#0000ff"&gt;= new &lt;/font&gt;&lt;font color="#000000"&gt;TSocket(&lt;/font&gt;&lt;font color="#808080"&gt;"localhost"&lt;/font&gt;&lt;font color="#000000"&gt;, &lt;/font&gt;&lt;font color="#800000"&gt;9160&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
                    &lt;/font&gt;&lt;font color="#000000"&gt;TProtocol protocol &lt;/font&gt;&lt;font color="#0000ff"&gt;= new &lt;/font&gt;&lt;font color="#000000"&gt;TBinaryProtocol(transport)&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
                    &lt;/font&gt;&lt;font color="#000000"&gt;Cassandra.Client client &lt;/font&gt;&lt;font color="#0000ff"&gt;= new &lt;/font&gt;&lt;font color="#000000"&gt;Cassandra.Client(protocol)&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
                     &lt;br /&gt;
                    &lt;/font&gt;&lt;font color="#000000"&gt;Console.WriteLine(&lt;/font&gt;&lt;font color="#808080"&gt;"Opening connection"&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
                    &lt;/font&gt;&lt;font color="#000000"&gt;transport.Open()&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
        &lt;br /&gt;
                    &lt;/font&gt;&lt;font color="#000000"&gt;System.Text.Encoding utf8Encoding &lt;/font&gt;&lt;font color="#0000ff"&gt;= &lt;/font&gt;&lt;font color="#000000"&gt;System.Text.Encoding.UTF8&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
        &lt;br /&gt;
                    long &lt;/font&gt;&lt;font color="#000000"&gt;timeStamp &lt;/font&gt;&lt;font color="#0000ff"&gt;= &lt;/font&gt;&lt;font color="#000000"&gt;DateTime.Now.Millisecond&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
                    &lt;/font&gt;&lt;font color="#000000"&gt;ColumnPath nameColumnPath &lt;/font&gt;&lt;font color="#0000ff"&gt;= new &lt;/font&gt;&lt;font color="#000000"&gt;ColumnPath()  &lt;br /&gt;
                                                {  &lt;br /&gt;
                                                    Column_family &lt;/font&gt;&lt;font color="#0000ff"&gt;= &lt;/font&gt;&lt;font color="#808080"&gt;"Standard1"&lt;/font&gt;&lt;font color="#000000"&gt;,  &lt;br /&gt;
                                                    Column &lt;/font&gt;&lt;font color="#0000ff"&gt;= &lt;/font&gt;&lt;font color="#000000"&gt;utf8Encoding.GetBytes(&lt;/font&gt;&lt;font color="#808080"&gt;"name"&lt;/font&gt;&lt;font color="#000000"&gt;)           &lt;br /&gt;
                                                }&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
        &lt;br /&gt;
                    &lt;/font&gt;&lt;font color="#000000"&gt;Console.WriteLine(&lt;/font&gt;&lt;font color="#808080"&gt;"Inserting name columns"&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
        &lt;br /&gt;
                    &lt;/font&gt;&lt;font color="#006400"&gt;//Insert the data into the column 'name'           &lt;br /&gt;
                    &lt;/font&gt;&lt;font color="#000000"&gt;client.insert(&lt;/font&gt;&lt;font color="#808080"&gt;"Keyspace1"&lt;/font&gt;&lt;font color="#000000"&gt;,           &lt;br /&gt;
                                  &lt;/font&gt;&lt;font color="#808080"&gt;"1"&lt;/font&gt;&lt;font color="#000000"&gt;,           &lt;br /&gt;
                                  nameColumnPath,            &lt;br /&gt;
                                  utf8Encoding.GetBytes(&lt;/font&gt;&lt;font color="#808080"&gt;"Joe Bloggs"&lt;/font&gt;&lt;font color="#000000"&gt;),           &lt;br /&gt;
                                  timeStamp,            &lt;br /&gt;
                                  ConsistencyLevel.ONE)&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
        &lt;br /&gt;
                    &lt;/font&gt;&lt;font color="#000000"&gt;client.insert(&lt;/font&gt;&lt;font color="#808080"&gt;"Keyspace1"&lt;/font&gt;&lt;font color="#000000"&gt;,           &lt;br /&gt;
                                  &lt;/font&gt;&lt;font color="#808080"&gt;"2"&lt;/font&gt;&lt;font color="#000000"&gt;,           &lt;br /&gt;
                                  nameColumnPath,            &lt;br /&gt;
                                  utf8Encoding.GetBytes(&lt;/font&gt;&lt;font color="#808080"&gt;"Joe Soap"&lt;/font&gt;&lt;font color="#000000"&gt;),           &lt;br /&gt;
                                  timeStamp,            &lt;br /&gt;
                                  ConsistencyLevel.ONE)&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
        &lt;br /&gt;
                    &lt;/font&gt;&lt;font color="#006400"&gt;//Simple single value get using the key to get column 'name'           &lt;br /&gt;
                    &lt;/font&gt;&lt;font color="#000000"&gt;ColumnOrSuperColumn returnedColumn &lt;/font&gt;&lt;font color="#0000ff"&gt;= &lt;/font&gt;&lt;font color="#000000"&gt;client.&lt;/font&gt;&lt;font color="#0000ff"&gt;get&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#808080"&gt;"Keyspace1"&lt;/font&gt;&lt;font color="#000000"&gt;, &lt;/font&gt;&lt;font color="#808080"&gt;"1"&lt;/font&gt;&lt;font color="#000000"&gt;, nameColumnPath, ConsistencyLevel.ONE)&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
                    &lt;/font&gt;&lt;font color="#000000"&gt;Console.WriteLine(&lt;/font&gt;&lt;font color="#808080"&gt;"Column Data in Keyspace1/Standard1: name: {0}, value: {1}"&lt;/font&gt;&lt;font color="#000000"&gt;,           &lt;br /&gt;
                                      utf8Encoding.GetString(returnedColumn.Column.Name),            &lt;br /&gt;
                                      utf8Encoding.GetString(returnedColumn.Column.Value))&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
        &lt;br /&gt;
                    &lt;/font&gt;&lt;font color="#000000"&gt;Console.WriteLine(&lt;/font&gt;&lt;font color="#808080"&gt;"Getting splice range"&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
        &lt;br /&gt;
                    &lt;/font&gt;&lt;font color="#006400"&gt;//Read an entire row           &lt;br /&gt;
                    &lt;/font&gt;&lt;font color="#000000"&gt;SlicePredicate predicate &lt;/font&gt;&lt;font color="#0000ff"&gt;= new &lt;/font&gt;&lt;font color="#000000"&gt;SlicePredicate()           &lt;br /&gt;
                                               {            &lt;br /&gt;
                                                  Slice_range &lt;/font&gt;&lt;font color="#0000ff"&gt;= new &lt;/font&gt;&lt;font color="#000000"&gt;SliceRange()           &lt;br /&gt;
                                                                {            &lt;br /&gt;
                                                                    &lt;/font&gt;&lt;font color="#006400"&gt;//Start and Finish cannot be null           &lt;br /&gt;
                                                                    &lt;/font&gt;&lt;font color="#000000"&gt;Start &lt;/font&gt;&lt;font color="#0000ff"&gt;= new byte&lt;/font&gt;&lt;font color="#000000"&gt;[&lt;/font&gt;&lt;font color="#800000"&gt;0&lt;/font&gt;&lt;font color="#000000"&gt;],  &lt;br /&gt;
                                                                    Finish &lt;/font&gt;&lt;font color="#0000ff"&gt;= new byte&lt;/font&gt;&lt;font color="#000000"&gt;[&lt;/font&gt;&lt;font color="#800000"&gt;0&lt;/font&gt;&lt;font color="#000000"&gt;],           &lt;br /&gt;
                                                                    Count  &lt;/font&gt;&lt;font color="#0000ff"&gt;= &lt;/font&gt;&lt;font color="#800000"&gt;10&lt;/font&gt;&lt;font color="#000000"&gt;,           &lt;br /&gt;
                                                                    Reversed &lt;/font&gt;&lt;font color="#0000ff"&gt;= false           &lt;br /&gt;
                                                                &lt;/font&gt;&lt;font color="#000000"&gt;}           &lt;br /&gt;
                                               }&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
        &lt;br /&gt;
                    &lt;/font&gt;&lt;font color="#000000"&gt;ColumnParent parent &lt;/font&gt;&lt;font color="#0000ff"&gt;= new &lt;/font&gt;&lt;font color="#000000"&gt;ColumnParent() { Column_family &lt;/font&gt;&lt;font color="#0000ff"&gt;= &lt;/font&gt;&lt;font color="#808080"&gt;"Standard1" &lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
                    &lt;/font&gt;&lt;font color="#000000"&gt;Dictionary&amp;lt;&lt;/font&gt;&lt;font color="#0000ff"&gt;string &lt;/font&gt;&lt;font color="#000000"&gt;, List&amp;lt;ColumnOrSuperColumn&amp;gt;&amp;gt; results &lt;/font&gt;&lt;font color="#0000ff"&gt;= &lt;/font&gt;&lt;font color="#000000"&gt;client.multiget_slice(&lt;/font&gt;&lt;font color="#808080"&gt;"Keyspace1"&lt;/font&gt;&lt;font color="#000000"&gt;,  &lt;br /&gt;
                                                                              &lt;/font&gt;&lt;font color="#0000ff"&gt;new &lt;/font&gt;&lt;font color="#000000"&gt;List&amp;lt;&lt;/font&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt;() { &lt;/font&gt;&lt;font color="#808080"&gt;"1"&lt;/font&gt;&lt;font color="#000000"&gt;, &lt;/font&gt;&lt;font color="#808080"&gt;"2"&lt;/font&gt;&lt;font color="#000000"&gt;},  &lt;br /&gt;
                                                                              parent,  &lt;br /&gt;
                                                                              predicate,  &lt;br /&gt;
                                                                              ConsistencyLevel.ONE)&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
        &lt;br /&gt;
                    foreach &lt;/font&gt;&lt;font color="#000000"&gt;(KeyValuePair&amp;lt;&lt;/font&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;font color="#000000"&gt;, List&amp;lt;ColumnOrSuperColumn&amp;gt;&amp;gt; resultPair &lt;/font&gt;&lt;font color="#0000ff"&gt;in &lt;/font&gt;&lt;font color="#000000"&gt;results)           &lt;br /&gt;
                    {            &lt;br /&gt;
                        Console.WriteLine(&lt;/font&gt;&lt;font color="#808080"&gt;"Key: {0}"&lt;/font&gt;&lt;font color="#000000"&gt;, resultPair.Key)&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
        &lt;br /&gt;
                        foreach &lt;/font&gt;&lt;font color="#000000"&gt;(ColumnOrSuperColumn resultColumn &lt;/font&gt;&lt;font color="#0000ff"&gt;in &lt;/font&gt;&lt;font color="#000000"&gt;resultPair.Value)           &lt;br /&gt;
                        {            &lt;br /&gt;
                            Column column &lt;/font&gt;&lt;font color="#0000ff"&gt;= &lt;/font&gt;&lt;font color="#000000"&gt;resultColumn.Column&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
                            &lt;/font&gt;&lt;font color="#000000"&gt;Console.WriteLine(&lt;/font&gt;&lt;font color="#808080"&gt;"name: {0}, value: {1}"&lt;/font&gt;&lt;font color="#000000"&gt;, utf8Encoding.GetString(column.Name), utf8Encoding.GetString(column.Value))&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
                        &lt;/font&gt;&lt;font color="#000000"&gt;}           &lt;br /&gt;
                    }            &lt;br /&gt;
        &lt;br /&gt;
                    Console.WriteLine(&lt;/font&gt;&lt;font color="#808080"&gt;"Closing connection"&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
                    &lt;/font&gt;&lt;font color="#000000"&gt;transport.Close()&lt;/font&gt;&lt;font color="#0000ff"&gt;;           &lt;br /&gt;
                &lt;/font&gt;&lt;font color="#000000"&gt;}           &lt;br /&gt;
            }            &lt;br /&gt;
        }&lt;/font&gt; &lt;/div&gt;
        &lt;/li&gt;
        &lt;li&gt;Hit F5 and watch the Application Output window. This is what you should see:&lt;br /&gt;
        &lt;br /&gt;
        &lt;a href="http://ridgway.co.za/images/ridgway_co_za/WindowsLiveWriter/8fe.NetDevelopersGuidetoGettingStartedwi_4F37/image_9.png"&gt;&lt;img border="0" width="619" height="466" style="border: 0px none ; display: block; float: none; margin-left: auto; margin-right: auto;" title="image" alt="image" src="http://www.ridgway.co.za/images/ridgway_co_za/WindowsLiveWriter/8fe.NetDevelopersGuidetoGettingStartedwi_4F37/image_thumb_3.png" /&gt;&lt;/a&gt; &lt;/li&gt;
    &lt;/ol&gt;
    &lt;/li&gt;
    &lt;br /&gt;
    Hopefully this is enough to get you going and have you fill in the remaining gaps. If you found it useful please post a comment. If the Cassandra guys would like to use the C# example they are welcome to it. Good luck!&lt;br /&gt;
&lt;/ol&gt;&lt;img src="http://ridgway.co.za/aggbug/196.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Eden Ridgway</dc:creator>
            <guid>http://ridgway.co.za/archive/2009/11/06/net-developers-guide-to-getting-started-with-cassandra.aspx</guid>
            <pubDate>Thu, 05 Nov 2009 22:32:51 GMT</pubDate>
            <comments>http://ridgway.co.za/archive/2009/11/06/net-developers-guide-to-getting-started-with-cassandra.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://ridgway.co.za/comments/commentRss/196.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Are Database Migration Frameworks Worth the Effort?</title>
            <link>http://ridgway.co.za/archive/2009/01/03/are-database-migration-frameworks-worth-the-effort.aspx</link>
            <description>&lt;p&gt;I’ve always used SQL scripts to manage database creation and migration. At my current company we have a database project with patch scripts that conditionally execute based on the database version. These scripts are simply run in sequence by an installer which stores the current database version as a database extended property. The approach relies on version based naming of SQL scripts and developers to remember to update the patch script whenever they make a structure or stored procedure change. Of course one could try to use a tool such as Redgate SQL compare to generate diff patch scripts but that won’t always suffice as that won’t capture refactoring such as column name changes or data migration (for more read &lt;a target="_blank" href="http://blog.liquibase.org/2007/06/the-problem-with-database-diffs.html"&gt;The Problem with Database Diffs&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;The use of SQL scripts is not without it’s problems. The most annoying of these is that a patch script may break as SQL will parse and validate your script against the existing table structure even if the statements are not going to run due to version check condition. This forces one to use nasty EXEC/sp_execute alter/create statements with double escaped strings (Yuck!). I find the following particularly problematic with this approach:&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;The string based SQL statements will always pass validation even though when they are executed they may be completely screwed &lt;/li&gt;
    &lt;li&gt;It is impractical to generate these by hand and the best way to create them is to use SQL Management Studio. &lt;/li&gt;
    &lt;li&gt;If your stored procedures are not wrapped in strings, to update the patch script requires you to script out the scripts from the database. Basically this increases development friction and discourages updating of the patch script. &lt;/li&gt;
    &lt;li&gt;It becomes difficult to determine when a structural change was made as one has to trawl through huge SQL scripts and it is not easy to use a regex search to find a change. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Hence I long for something a little more strongly typed, which is why the growing number of .Net based Database Migration frameworks have caught my eye. I want to be sure that there isn’t something obvious that I was missing out by not using one. Fortunately Ben Scheirman has done a fair amount of research already and wrote a fairly good round up of &lt;a target="_blank" href="http://flux88.com/blog/net-database-migration-tool-roundup/"&gt;available .Net migration tools&lt;/a&gt;. Looking at the tools there are clearly two different types of frameworks available:&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;&lt;strong&gt;Structured SQL script execution&lt;/strong&gt; – These tools provide a framework under which SQL scripts will be executed to create and upgrade a database to a specific version. Examples of these are: &lt;a target="_blank" href="http://code.google.com/p/tarantino/wiki/DatabaseChangeManagement"&gt;Tarantino&lt;/a&gt; and &lt;a target="_blank" href="http://www.liquibase.org/"&gt;LiquiBase&lt;/a&gt;. &lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Rails like Active Record Migration&lt;/strong&gt; – Commands to upgrade or downgrade the database schema and data can be coded in a .Net language, with the possibility of executing SQL statements if required. Tools that fall into this category are: &lt;a target="_blank" href="http://www.rikware.com/RikMigrations.html"&gt;RikMigrations&lt;/a&gt;, &lt;a target="_blank" href="http://subsonicproject.com/2-1-pakala/subsonic-using-migrations/"&gt;SubSonic Migrations&lt;/a&gt;, &lt;a target="_blank" href="http://codebetter.com/blogs/jacob.lewallen/archive/2008/04/25/a-first-look-at-machine-migrations.aspx"&gt;Machine.Migrations&lt;/a&gt; and &lt;a target="_blank" href="http://code.google.com/p/migratordotnet/"&gt;Migrator.Net&lt;/a&gt;. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The obvious question that springs to mind when looking at these frameworks is whether or not the additional development friction (additional tasks that must be performed during the course of development) is worth the benefit. To be honest I don’t see a massive difference between the structured SQL script execution approach and what I’ve been doing all along. However the likes of &lt;a target="_blank" href="http://www.liquibase.org/"&gt;LiquiBase&lt;/a&gt; do provide a functionality that nicely captures database refactorings and diffs, so maybe it could be used as more of a general toolset. However the Active Migration approach would be a more radical departure so I’d like to explore that more.&lt;/p&gt;
&lt;p&gt;Here are my thoughts on Active Record Migration like frameworks:&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;Best paired with an ORM framework, such as &lt;a target="_blank" href="http://www.hibernate.org/343.html"&gt;NHibernate&lt;/a&gt; or &lt;a target="_blank" href="http://subsonicproject.com/"&gt;Subsonic&lt;/a&gt;, where one is not writing a lot of custom SQL and hence the the upgrade classes can be kept clean and focus on structural and data migration. That is not to say that there will not be benefit to having them execute a lot of SQL statements to add/update stored procedures, it is just that it may get a little messy and possibly tedious. &lt;/li&gt;
    &lt;li&gt;Using C# code to do database change would provide an opportunity to use something like log4net to dump out progress information. I've always longed for a decent way of doing this that doesn't involve a custom proc that inserts into a table. I really like the idea of having a degree of compile time checking for the database changes. Of course with SQL scripts you could always run them on each build and if they break, you fail the build. &lt;/li&gt;
    &lt;li&gt;The whole idea of downgrading a database scares me because if someone accidently points an old version of an application (with automatic migration logic) to the database (think xcopy deployment) you could end up losing tables and data. Of course one should always backup a database before doing a deployment, but I’m talking about a situation where one doesn’t know it is pointing to the wrong database until it is too late. I hope these tools backup the database before applying changes. In my mind a downgrade should only be performed if a rollout fails and one has to revert to a backup taken before the upgrade was undertaken.&lt;/li&gt;
    &lt;li&gt;I really like the idea of using anonymous objects to insert data into the database (&lt;a target="_blank" href="http://www.codethinked.com/post/2008/12/16/Migrations-in-C-using-RikMigrations.aspx"&gt;RikiMigration supports this&lt;/a&gt;) and avoiding the need to write insert statements. &lt;/li&gt;
    &lt;li&gt;Do you not run into potential development concurrency and structuring issues? So for example during a development cycle does one dump all changes into one class or into several? &lt;/li&gt;
    &lt;li&gt;The database vendor abstraction that is can provide is only attractive to a small number of projects. Furthermore one invariably will need to execute vendor specific statements and is best suited to a multi-vendor ORM such as NHibernate.&lt;/li&gt;
    &lt;li&gt;The approach may not fly in an organization where a DBA must review all SQL changes. Although I don’t see any reason why the frameworks couldn’t generate these for you.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I think if I was currently working on a project that used an ORM like NHibernate or LINQ to Entities, the migration frameworks would be a lot more appealing. However with other types of projects I’m worried that the additional effort isn’t really going to be worth the benefit.&lt;/p&gt;
&lt;p&gt;Am I missing any other potential benefits (or problems)? I would really like to hear if there are other compelling reasons to adopt the approach.&lt;/p&gt;&lt;img src="http://ridgway.co.za/aggbug/195.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Eden Ridgway</dc:creator>
            <guid>http://ridgway.co.za/archive/2009/01/03/are-database-migration-frameworks-worth-the-effort.aspx</guid>
            <pubDate>Sat, 03 Jan 2009 11:52:03 GMT</pubDate>
            <comments>http://ridgway.co.za/archive/2009/01/03/are-database-migration-frameworks-worth-the-effort.aspx#feedback</comments>
            <wfw:commentRss>http://ridgway.co.za/comments/commentRss/195.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Using a CTE to Allocate Tickets to Timeslots</title>
            <link>http://ridgway.co.za/archive/2008/01/27/using-a-cte-to-allocate-tickets-to-timeslots.aspx</link>
            <description>&lt;p&gt;SQL Server Common Table Expressions (CTEs) are most often used to solve problems such as paging and hierarchical queries, however in this post I want to demonstrate another use: booking of timeslots. If you were writing a system for an attraction with predefined timeslots, say to see the damper in the Taipei 101 building, you would need to be able to distribute the allocation of tickets over these timeslots. So if a group of 16 people arrived, depending on the space available in the timeslot they may be allocated over several timeslots and would have to patiently wait until their turn came around.&lt;/p&gt;
&lt;p&gt;The most obvious way to solve this problem is to use a looping structure that moves through the timeslots, allocates the tickets and reduces the number of tickets available for that timeslot. Unfortunately to ensure that slots are not over booked while this is going on, one has to lock the tables affected by the allocation process. This can cause performance and concurrency issues as the number of requested tickets and therefore the lock duration increases. A more efficient and elegant solution is to use the inherent looping/recursive nature of a CTE to do this allocation in one step. So instead of doing a loop, insert into select, loop again cycle, the code can simply do a single insert into select statement to block out the allocated timeslots in one implicit transaction.&lt;/p&gt;
&lt;p&gt;To demonstrate the approach, let us take a scenario where we want to allocate 16 tickets. The number of remaining places available per timeslot are as per the diagram below.&lt;/p&gt;
&lt;p style="text-align: left;"&gt;&lt;a href="http://ridgway.co.za/images/ridgway_co_za/WindowsLiveWriter/UsingaCTEtoAllocateTicketstoTimeslots_9DC2/Timeslots.gif"&gt;&lt;img width="260" height="84" border="0" src="http://ridgway.co.za/images/ridgway_co_za/WindowsLiveWriter/UsingaCTEtoAllocateTicketstoTimeslots_9DC2/clip_image001_thumb.gif" alt="clip_image001" style="border-width: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Our simplified database would therefore have a Timeslot table that contains the time and the running available capacity for each one, like this:&lt;/p&gt;
&lt;table cellspacing="0" cellpadding="2" border="1" style="border: 1px solid black;"&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td width="188" valign="top"&gt;Time&lt;/td&gt;
            &lt;td width="210" valign="top"&gt;Available Capacity&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td width="188" valign="top"&gt;1 Jan 2008 08:00:00&lt;/td&gt;
            &lt;td width="210" valign="top"&gt;0&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td width="188" valign="top"&gt;1 Jan 2008 08:20:00&lt;/td&gt;
            &lt;td width="210" valign="top"&gt;5&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td width="188" valign="top"&gt;1 Jan 2008 08:40:00&lt;/td&gt;
            &lt;td width="210" valign="top"&gt;0&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td width="188" valign="top"&gt;1 Jan 2008 09:00:00&lt;/td&gt;
            &lt;td width="210" valign="top"&gt;7&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td width="188" valign="top"&gt;1 Jan 2008 09:20:00&lt;/td&gt;
            &lt;td width="210" valign="top"&gt;2&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td width="188" valign="top"&gt;1 Jan 2008 09:40:00&lt;/td&gt;
            &lt;td width="210" valign="top"&gt;10&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;We want to allocate 16 tickets across those timeslot. So the CTE we create should operate in the following manner:&lt;/p&gt;
&lt;p style="text-align: left;"&gt;&lt;a href="http://ridgway.co.za/images/ridgway_co_za/WindowsLiveWriter/UsingaCTEtoAllocateTicketstoTimeslots_9DC2/clip_image002_2.gif"&gt;&lt;img width="429" height="298" border="0" src="http://ridgway.co.za/images/ridgway_co_za/WindowsLiveWriter/UsingaCTEtoAllocateTicketstoTimeslots_9DC2/clip_image002_thumb.gif" alt="clip_image002" style="border: 0px none ;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The CTE to do this looks like this:&lt;/p&gt;
&lt;div class="code"&gt;&lt;font color="#0000ff"&gt;DECLARE &lt;/font&gt;&lt;font color="#000000"&gt;@SeatsRequested &lt;/font&gt;&lt;font color="#0000ff"&gt;SMALLINT     &lt;br /&gt;
&lt;br /&gt;
SET &lt;/font&gt;&lt;font color="#000000"&gt;@SeatsRequested &lt;/font&gt;&lt;font color="#0000ff"&gt;= &lt;/font&gt;&lt;font color="#800000"&gt;16&lt;/font&gt;&lt;font color="#0000ff"&gt;;     &lt;br /&gt;
&lt;br /&gt;
WITH &lt;/font&gt;&lt;font color="#000000"&gt;TimeSlotAllocation (Time, SeatsAllocated, SeatsLeftToAllocate) &lt;/font&gt;&lt;font color="#0000ff"&gt;as     &lt;br /&gt;
&lt;/font&gt;&lt;font color="#000000"&gt;(     &lt;br /&gt;
    &lt;/font&gt;&lt;font color="#006400"&gt;--Find the first time slot to use     &lt;br /&gt;
    &lt;/font&gt;&lt;font color="#0000ff"&gt;SELECT TOP &lt;/font&gt;&lt;font color="#800000"&gt;1     &lt;br /&gt;
        &lt;/font&gt;&lt;font color="#000000"&gt;Time,     &lt;br /&gt;
        dbo.MinNumber(@SeatsRequested, AvailableCapacity) &lt;/font&gt;&lt;font color="#0000ff"&gt;as &lt;/font&gt;&lt;font color="#000000"&gt;SeatsAllocated,     &lt;br /&gt;
        @SeatsRequested - dbo.MinNumber(@SeatsRequested, AvailableCapacity) &lt;/font&gt;&lt;font color="#0000ff"&gt;as &lt;/font&gt;&lt;font color="#000000"&gt;SeatsLeftToAllocate     &lt;br /&gt;
    &lt;/font&gt;&lt;font color="#0000ff"&gt;FROM     &lt;br /&gt;
        &lt;/font&gt;&lt;font color="#000000"&gt;Timeslot     &lt;br /&gt;
    &lt;/font&gt;&lt;font color="#0000ff"&gt;WHERE     &lt;br /&gt;
        &lt;/font&gt;&lt;font color="#000000"&gt;AvailableCapacity &amp;gt; &lt;/font&gt;&lt;font color="#800000"&gt;0     &lt;br /&gt;
    &lt;/font&gt;&lt;font color="#0000ff"&gt;ORDER BY     &lt;br /&gt;
        &lt;/font&gt;&lt;font color="#000000"&gt;Time     &lt;br /&gt;
     &lt;br /&gt;
    &lt;/font&gt;&lt;font color="#0000ff"&gt;UNION ALL     &lt;br /&gt;
     &lt;br /&gt;
    &lt;/font&gt;&lt;font color="#006400"&gt;--Sequentially find the other timeslots that can be used to fulfill the sale request     &lt;br /&gt;
    &lt;/font&gt;&lt;font color="#0000ff"&gt;SELECT  &lt;br /&gt;
        &lt;/font&gt;&lt;font color="#000000"&gt;TS.Time,     &lt;br /&gt;
        dbo.MinNumber(TSA.SeatsLeftToAllocate, TS.AvailableCapacity),      &lt;br /&gt;
        TSA.SeatsLeftToAllocate - dbo.MinNumber(TSA.SeatsLeftToAllocate, TS.AvailableCapacity)      &lt;br /&gt;
    &lt;/font&gt;&lt;font color="#0000ff"&gt;FROM     &lt;br /&gt;
        &lt;/font&gt;&lt;font color="#000000"&gt;Timeslot TS     &lt;br /&gt;
         &lt;br /&gt;
        &lt;/font&gt;&lt;font color="#006400"&gt;--Join on to the next timeslot     &lt;br /&gt;
        &lt;/font&gt;&lt;font color="#0000ff"&gt;INNER JOIN &lt;/font&gt;&lt;font color="#000000"&gt;TimeSlotAllocation TSA &lt;/font&gt;&lt;font color="#0000ff"&gt;ON     &lt;br /&gt;
            &lt;/font&gt;&lt;font color="#000000"&gt;TS.Time &lt;/font&gt;&lt;font color="#0000ff"&gt;= DATEADD&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#0000ff"&gt;MINUTE&lt;/font&gt;&lt;font color="#000000"&gt;, &lt;/font&gt;&lt;font color="#800000"&gt;20&lt;/font&gt;&lt;font color="#000000"&gt;, TSA.Time)     &lt;br /&gt;
    &lt;/font&gt;&lt;font color="#0000ff"&gt;WHERE     &lt;br /&gt;
        &lt;/font&gt;&lt;font color="#000000"&gt;SeatsLeftToAllocate &amp;gt; &lt;/font&gt;&lt;font color="#800000"&gt;0     &lt;br /&gt;
&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt; &lt;/div&gt;
&lt;p&gt;You’ll notice the code relies on a user defined function, MinNumber which simply returns the minimum value of the two supplied parameters. As you can see the logic is pretty straight forward:&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;Find the first available timeslot. &lt;/li&gt;
    &lt;li&gt;Allocate the lesser of the number of SeatsLeftToAllocate or the available timeslot capacity. &lt;/li&gt;
    &lt;li&gt;Store the number of tickets remaining in SeatsLeftToAllocate &lt;/li&gt;
    &lt;li&gt;Move on to the next timeslot by adding the number of minutes between timeslots. &lt;/li&gt;
    &lt;li&gt;Repeat steps 2 to 4 until there are no SeatsLeftToAllocate. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Of course the final solution would include other logic, such as bounding the allocation of timeslots by day and checking that all tickets had been allocated, but this is merely an illustration of an approach.&lt;/p&gt;
&lt;p&gt;If you want to play around with a working example, &lt;a href="http://www.ridgway.co.za/Demos/Timeslot Allocation with a CTE.zip"&gt;here is the code&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://ridgway.co.za/aggbug/192.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Eden Ridgway</dc:creator>
            <guid>http://ridgway.co.za/archive/2008/01/27/using-a-cte-to-allocate-tickets-to-timeslots.aspx</guid>
            <pubDate>Sun, 27 Jan 2008 09:25:41 GMT</pubDate>
            <comments>http://ridgway.co.za/archive/2008/01/27/using-a-cte-to-allocate-tickets-to-timeslots.aspx#feedback</comments>
            <wfw:commentRss>http://ridgway.co.za/comments/commentRss/192.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Using a Common Table Expression (CTE) to Generate a Date Range</title>
            <link>http://ridgway.co.za/archive/2007/11/23/using-a-common-table-expression-cte-to-generate-a-date.aspx</link>
            <description>There are times when you date reliant data that has gaps in it but you need a query that includes days even where data is missing. The data source may be a sales table where there may be days that no sales where made but you want to generate a calendar like cross-tab query for every day in a period. When I was asked by a colleague to help him with a similar problem it struck me that we could leverage a SQL 2005 CTE in a user defined function to act as a date range source for the query on which we could left join and fill in the missing days.&lt;br /&gt;
&lt;br /&gt;
The solution is quite simple, all you need is a CTE that starts and the start date and recursively joins on to itself using DATEADD plus a day until it reaches the end date. Here is the function that I wrote:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="code"&gt; &lt;font color="blue"&gt;CREATE FUNCTION &lt;/font&gt;&lt;font color="black"&gt;GetDateRange &lt;br /&gt;
(&lt;br /&gt;
    @StartDate &lt;/font&gt;&lt;font color="blue"&gt;DateTime&lt;/font&gt;&lt;font color="black"&gt;, &lt;br /&gt;
    @EndDate &lt;/font&gt;&lt;font color="blue"&gt;DateTime&lt;br /&gt;
&lt;/font&gt;&lt;font color="black"&gt;)&lt;br /&gt;
RETURNS @DateRangeList &lt;/font&gt;&lt;font color="blue"&gt;TABLE &lt;br /&gt;
&lt;/font&gt;&lt;font color="black"&gt;(&lt;br /&gt;
    Date &lt;/font&gt;&lt;font color="blue"&gt;DateTime NOT NULL&lt;br /&gt;
&lt;/font&gt;&lt;font color="black"&gt;)&lt;br /&gt;
&lt;/font&gt;&lt;font color="blue"&gt;AS &lt;br /&gt;
BEGIN&lt;br /&gt;
    IF &lt;/font&gt;&lt;font color="black"&gt;@StartDate &amp;gt; @EndDate&lt;br /&gt;
    &lt;/font&gt;&lt;font color="blue"&gt;BEGIN&lt;br /&gt;
        &lt;/font&gt;&lt;font color="darkgreen"&gt;--Unfortunately you cannot raise an error in a UDF so simply return no rows&lt;br /&gt;
        &lt;/font&gt;&lt;font color="blue"&gt;RETURN&lt;br /&gt;
    END;&lt;br /&gt;
&lt;br /&gt;
    WITH &lt;/font&gt;&lt;font color="black"&gt;DateRange(Date) &lt;/font&gt;&lt;font color="blue"&gt;AS&lt;br /&gt;
    &lt;/font&gt;&lt;font color="black"&gt;(&lt;br /&gt;
        &lt;/font&gt;&lt;font color="blue"&gt;SELECT&lt;br /&gt;
            &lt;/font&gt;&lt;font color="black"&gt;@StartDate Date&lt;br /&gt;
        &lt;/font&gt;&lt;font color="blue"&gt;UNION ALL&lt;br /&gt;
        SELECT&lt;br /&gt;
            DATEADD&lt;/font&gt;&lt;font color="black"&gt;(day, &lt;/font&gt;&lt;font color="maroon"&gt;1&lt;/font&gt;&lt;font color="black"&gt;, Date) Date&lt;br /&gt;
        &lt;/font&gt;&lt;font color="blue"&gt;FROM&lt;br /&gt;
            &lt;/font&gt;&lt;font color="black"&gt;DateRange&lt;br /&gt;
        &lt;/font&gt;&lt;font color="blue"&gt;WHERE&lt;br /&gt;
            &lt;/font&gt;&lt;font color="black"&gt;Date &amp;lt; @EndDate&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
    &lt;/font&gt;&lt;font color="blue"&gt;INSERT &lt;/font&gt;&lt;font color="black"&gt;@DateRangeList&lt;br /&gt;
    &lt;/font&gt;&lt;font color="blue"&gt;SELECT &lt;/font&gt;&lt;font color="black"&gt;Date &lt;br /&gt;
    &lt;/font&gt;&lt;font color="blue"&gt;FROM &lt;/font&gt;&lt;font color="black"&gt;DateRange&lt;br /&gt;
    &lt;/font&gt;&lt;font color="darkgreen"&gt;--You could remove Maximum Recursion level constraint by specifying a MaxRecusion of zero&lt;br /&gt;
    &lt;/font&gt;&lt;font color="blue"&gt;OPTION &lt;/font&gt;&lt;font color="black"&gt;(MaxRecursion &lt;/font&gt;&lt;font color="maroon"&gt;10000&lt;/font&gt;&lt;font color="black"&gt;)&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
&lt;br /&gt;
    RETURN&lt;br /&gt;
&lt;br /&gt;
END;&lt;/font&gt; 	&lt;/div&gt;
&lt;br /&gt;
The performance of the query is pretty good, but is almost identical to using a temp table/table variable and a loop to generate the same data. On my P4 2.8GHZ machine  at home both approaches generate a month's worth of days in 16ms and a year's worth in 30ms. I have to say I was somewhat surprised to find this out since I expected it to be faster but I suppose the inserts into the table variable negate the possible speed up. Regardless it is an interesting approach that I thought I'd share with you.&lt;img src="http://ridgway.co.za/aggbug/190.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Eden Ridgway</dc:creator>
            <guid>http://ridgway.co.za/archive/2007/11/23/using-a-common-table-expression-cte-to-generate-a-date.aspx</guid>
            <pubDate>Fri, 23 Nov 2007 06:51:14 GMT</pubDate>
            <comments>http://ridgway.co.za/archive/2007/11/23/using-a-common-table-expression-cte-to-generate-a-date.aspx#feedback</comments>
            <wfw:commentRss>http://ridgway.co.za/comments/commentRss/190.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Profiler for SQL Express</title>
            <link>http://ridgway.co.za/archive/2007/07/10/profiler-for-sql-express.aspx</link>
            <description>For those of you who are doing things on the cheap and only using SQL Express, you'll be glad to know that there is an open source &lt;a target="_blank" href="http://sqlprofiler.googlepages.com/"&gt;SQL Express profiler&lt;/a&gt; project. As one would expect it is pretty basic, but has all the important features, like the ability to filter and select the events and columns to trace. I had a look around the code and it is pretty simple (it could do with some more comments though &lt;img src="/Providers/BlogEntryEditor/FCKeditor/editor/images/smiley/msn/regular_smile.gif" alt="" /&gt;), so it should be easy enough to extend should you want to.&lt;img src="http://ridgway.co.za/aggbug/185.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Eden Ridgway</dc:creator>
            <guid>http://ridgway.co.za/archive/2007/07/10/profiler-for-sql-express.aspx</guid>
            <pubDate>Tue, 10 Jul 2007 04:45:00 GMT</pubDate>
            <comments>http://ridgway.co.za/archive/2007/07/10/profiler-for-sql-express.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://ridgway.co.za/comments/commentRss/185.aspx</wfw:commentRss>
        </item>
        <item>
            <title>WatiN - A .Net IE Testing Framework</title>
            <link>http://ridgway.co.za/archive/2007/01/11/177.aspx</link>
            <description>Today I discovered &lt;a href="http://watin.sourceforge.net" target="_blank"&gt;WatiN&lt;/a&gt; which is a &lt;a href="http://www.openqa.org/watir/"&gt;Watir&lt;/a&gt; inspired testing framework for .Net that automates Internet Explorer actions.  Here are some of the more notable features of the framework:&lt;br /&gt;
&lt;ul&gt;
    &lt;li&gt;Support for frames (cross domain) and iframes&lt;/li&gt;
    &lt;li&gt;Support for popup dialogs like alert, confirm, login etc.&lt;/li&gt;
    &lt;li&gt;Support for HTML dialogs (modal and modeless)&lt;/li&gt;
    &lt;li&gt;Supports AJAX website testing.&lt;/li&gt;
    &lt;li&gt;Works with Internet Explorer 6 and Internet Explorer 7&lt;/li&gt;
&lt;/ul&gt;
The WatiN site has pretty good documentation documentation to get you started.  Furthermore Richard Griffin ported the &lt;a href="http://www.hanselman.com/blog/NewReleaseOfWatirMakerNowWatirRecorder.aspx" target="_blank"&gt;WATiR WebRecorder++&lt;/a&gt; to create &lt;a href="http://blogs.conchango.com/richardgriffin/archive/2006/10/18/WATiN-web-recorder_2B002B00_-prototype.aspx" target="_blank"&gt;WATiN WebRecorder++&lt;/a&gt; so there is a quick way of creating initial test scripts.  Richard also has some &lt;a href="http://blogs.conchango.com/richardgriffin/archive/2006/11/14/Testing-Design-Pattern-for-using-WATiR_2F00_N.aspx"&gt;great advice&lt;/a&gt; on test case design which I'm going to get my team to read.&lt;br /&gt;
&lt;br /&gt;
This may be just what I've been looking for to promote more automated web testing at my current company &lt;img alt="" src="/Providers/BlogEntryEditor/FCKeditor/editor/images/smiley/msn/teeth_smile.gif" /&gt;.&lt;img src="http://ridgway.co.za/aggbug/177.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Eden Ridgway</dc:creator>
            <guid>http://ridgway.co.za/archive/2007/01/11/177.aspx</guid>
            <pubDate>Thu, 11 Jan 2007 04:20:30 GMT</pubDate>
            <comments>http://ridgway.co.za/archive/2007/01/11/177.aspx#feedback</comments>
            <wfw:commentRss>http://ridgway.co.za/comments/commentRss/177.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Using GraphViz to Generate ERDs for SQL Server</title>
            <link>http://ridgway.co.za/archive/2007/01/05/GraphVizTtoGenerateERDsforSQL.aspx</link>
            <description>When working on a new system you usually want to be able to quickly get a simple view of the database.  Usually this involves using Enterprise Manager (or Management Studio) to create a diagram and auto-arrange the tables for you.  However it usually does a pretty poor job of this and any diagram you print ends up spanning multiple pages.  What I wanted is something that would do a decent job of arranging an ERD for me.  I decided that a good candidate for this was &lt;a href="http://www.graphviz.org/"&gt;GraphViz&lt;/a&gt; since it has a variety of layout engines and the DOT file format (that it uses to generate graphs from) is really simple.&lt;br /&gt;
&lt;br /&gt;
So I put together a SQL script and a batch file and generated the following graphs for Northwind.&lt;br /&gt;
&lt;br /&gt;
&lt;img width="365" height="137" alt="" src="/images/ridgway_co_za/Northwind_ERD_Dot.png" /&gt;&lt;img alt="" src="/images/ridgway_co_za/Northwind_ERD_Neato.png" /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For those of you who don’t care about the implementation details, here are the files: &lt;a href="http://www.ridgway.co.za/images/ridgway_co_za/GraphVizGenerator.zip"&gt;GraphVizGenerator.zip&lt;/a&gt;.  The batch file assumes that osql is in your path, that you have used the default install directory for GraphViz and that you use integrated authentication to connect to your server, so you will need to change this if this is not the case.  To use the batch file, run the following command:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="code"&gt; "Generate Diagram.bat" ServerName DatabaseName&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="code"&gt; "Generate Diagram.bat" (local) Northwind&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
Okay, so how does it all work?  Well the SQL script uses union statements to return a row per line in our DOT file, like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="code"&gt; &lt;font color="blue"&gt;SELECT&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;'digraph G {'&lt;br /&gt;
&lt;br /&gt;
&lt;/font&gt;&lt;font color="blue"&gt;UNION ALL&lt;br /&gt;
&lt;br /&gt;
SELECT&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;'  "' &lt;/font&gt;&lt;font color="black"&gt;+ TABLE_NAME + &lt;/font&gt;&lt;font color="#808080"&gt;'"[shape=box];'&lt;br /&gt;
&lt;/font&gt;&lt;font color="blue"&gt;FROM&lt;br /&gt;
    &lt;/font&gt;&lt;font color="black"&gt;INFORMATION_SCHEMA.TABLES&lt;br /&gt;
&lt;/font&gt;&lt;font color="blue"&gt;WHERE&lt;br /&gt;
    &lt;/font&gt;&lt;font color="black"&gt;TABLE_TYPE &lt;/font&gt;&lt;font color="blue"&gt;= &lt;/font&gt;&lt;font color="#808080"&gt;'BASE TABLE' &lt;/font&gt;&lt;font color="blue"&gt;AND&lt;br /&gt;
    &lt;/font&gt;&lt;font color="black"&gt;TABLE_NAME &lt;/font&gt;&lt;font color="blue"&gt;NOT IN &lt;/font&gt;&lt;font color="black"&gt;(&lt;/font&gt;&lt;font color="#808080"&gt;'dtproperties'&lt;/font&gt;&lt;font color="black"&gt;, &lt;/font&gt;&lt;font color="#808080"&gt;'sysdiagrams'&lt;/font&gt;&lt;font color="black"&gt;)&lt;br /&gt;
         &lt;br /&gt;
&lt;/font&gt;&lt;font color="blue"&gt;UNION ALL&lt;br /&gt;
&lt;br /&gt;
SELECT&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;'  "' &lt;/font&gt;&lt;font color="black"&gt;+ FKRefTable + &lt;/font&gt;&lt;font color="#808080"&gt;'" -&amp;gt; "' &lt;/font&gt;&lt;font color="black"&gt;+ PKTable + &lt;/font&gt;&lt;font color="#808080"&gt;'";'&lt;br /&gt;
&lt;/font&gt;&lt;font color="blue"&gt;FROM&lt;br /&gt;
    #&lt;/font&gt;&lt;font color="black"&gt;Dependencies&lt;br /&gt;
&lt;br /&gt;
&lt;/font&gt;&lt;font color="blue"&gt;UNION ALL&lt;br /&gt;
&lt;br /&gt;
SELECT&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;'}' &lt;/font&gt; 	&lt;/div&gt;
&lt;br /&gt;
In a step before this I use the INFORMATION_SCHEMA constraints tables to populate a temporary table (#Dependencies) with the relationships (to keep the code simple).  I dump these results into a text file using the following command:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="code"&gt; osql -S %1 -d %2 -E -n -w 1000 -h-1 -i "GraphViz Generator.sql" -o "ERD.dot"&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
Note that I use the –h-1 parameter to ensure that the headers are not dumped into the file.  The –w 1000 also ensures that no wrapping of the columns occur.&lt;br /&gt;
&lt;br /&gt;
This generates a dot file that looks something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="code"&gt; &lt;font color="black"&gt;digraph G {&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"Categories"&lt;/font&gt;&lt;font color="black"&gt;[shape&lt;/font&gt;&lt;font color="blue"&gt;=&lt;/font&gt;&lt;font color="black"&gt;box]&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"CustomerCustomerDemo"&lt;/font&gt;&lt;font color="black"&gt;[shape&lt;/font&gt;&lt;font color="blue"&gt;=&lt;/font&gt;&lt;font color="black"&gt;box]&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"CustomerDemographics"&lt;/font&gt;&lt;font color="black"&gt;[shape&lt;/font&gt;&lt;font color="blue"&gt;=&lt;/font&gt;&lt;font color="black"&gt;box]&lt;/font&gt;&lt;font color="blue"&gt;; &lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"Customers"&lt;/font&gt;&lt;font color="black"&gt;[shape&lt;/font&gt;&lt;font color="blue"&gt;=&lt;/font&gt;&lt;font color="black"&gt;box]&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"Employees"&lt;/font&gt;&lt;font color="black"&gt;[shape&lt;/font&gt;&lt;font color="blue"&gt;=&lt;/font&gt;&lt;font color="black"&gt;box]&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"EmployeeTerritories"&lt;/font&gt;&lt;font color="black"&gt;[shape&lt;/font&gt;&lt;font color="blue"&gt;=&lt;/font&gt;&lt;font color="black"&gt;box]&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"Order Details"&lt;/font&gt;&lt;font color="black"&gt;[shape&lt;/font&gt;&lt;font color="blue"&gt;=&lt;/font&gt;&lt;font color="black"&gt;box]&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"Orders"&lt;/font&gt;&lt;font color="black"&gt;[shape&lt;/font&gt;&lt;font color="blue"&gt;=&lt;/font&gt;&lt;font color="black"&gt;box]&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"Products"&lt;/font&gt;&lt;font color="black"&gt;[shape&lt;/font&gt;&lt;font color="blue"&gt;=&lt;/font&gt;&lt;font color="black"&gt;box]&lt;/font&gt;&lt;font color="blue"&gt;; &lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"Region"&lt;/font&gt;&lt;font color="black"&gt;[shape&lt;/font&gt;&lt;font color="blue"&gt;=&lt;/font&gt;&lt;font color="black"&gt;box]&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"Shippers"&lt;/font&gt;&lt;font color="black"&gt;[shape&lt;/font&gt;&lt;font color="blue"&gt;=&lt;/font&gt;&lt;font color="black"&gt;box]&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"Suppliers"&lt;/font&gt;&lt;font color="black"&gt;[shape&lt;/font&gt;&lt;font color="blue"&gt;=&lt;/font&gt;&lt;font color="black"&gt;box]&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"Territories"&lt;/font&gt;&lt;font color="black"&gt;[shape&lt;/font&gt;&lt;font color="blue"&gt;=&lt;/font&gt;&lt;font color="black"&gt;box]&lt;/font&gt;&lt;font color="blue"&gt;; &lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"CustomerCustomerDemo" &lt;/font&gt;&lt;font color="black"&gt;-&amp;gt; &lt;/font&gt;&lt;font color="#808080"&gt;"CustomerDemographics"&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"CustomerCustomerDemo" &lt;/font&gt;&lt;font color="black"&gt;-&amp;gt; &lt;/font&gt;&lt;font color="#808080"&gt;"Customers"&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"Employees" &lt;/font&gt;&lt;font color="black"&gt;-&amp;gt; &lt;/font&gt;&lt;font color="#808080"&gt;"Employees"&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"EmployeeTerritories" &lt;/font&gt;&lt;font color="black"&gt;-&amp;gt; &lt;/font&gt;&lt;font color="#808080"&gt;"Employees"&lt;/font&gt;&lt;font color="blue"&gt;; &lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"EmployeeTerritories" &lt;/font&gt;&lt;font color="black"&gt;-&amp;gt; &lt;/font&gt;&lt;font color="#808080"&gt;"Territories"&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"Order Details" &lt;/font&gt;&lt;font color="black"&gt;-&amp;gt; &lt;/font&gt;&lt;font color="#808080"&gt;"Orders"&lt;/font&gt;&lt;font color="blue"&gt;; &lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"Order Details" &lt;/font&gt;&lt;font color="black"&gt;-&amp;gt; &lt;/font&gt;&lt;font color="#808080"&gt;"Products"&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"Orders" &lt;/font&gt;&lt;font color="black"&gt;-&amp;gt; &lt;/font&gt;&lt;font color="#808080"&gt;"Customers"&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"Orders" &lt;/font&gt;&lt;font color="black"&gt;-&amp;gt; &lt;/font&gt;&lt;font color="#808080"&gt;"Employees"&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"Orders" &lt;/font&gt;&lt;font color="black"&gt;-&amp;gt; &lt;/font&gt;&lt;font color="#808080"&gt;"Shippers"&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"Products" &lt;/font&gt;&lt;font color="black"&gt;-&amp;gt; &lt;/font&gt;&lt;font color="#808080"&gt;"Categories"&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"Products" &lt;/font&gt;&lt;font color="black"&gt;-&amp;gt; &lt;/font&gt;&lt;font color="#808080"&gt;"Suppliers"&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#808080"&gt;"Territories" &lt;/font&gt;&lt;font color="black"&gt;-&amp;gt; &lt;/font&gt;&lt;font color="#808080"&gt;"Region"&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
 &lt;/font&gt;&lt;font color="black"&gt;}&lt;/font&gt; 	&lt;/div&gt;
&lt;br /&gt;
&lt;p class="MsoNormal"&gt;This is then used to spit out five ERDs using different layouts so that you can choose the one that you find most useful.&lt;/p&gt;&lt;img src="http://ridgway.co.za/aggbug/176.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Eden Ridgway</dc:creator>
            <guid>http://ridgway.co.za/archive/2007/01/05/GraphVizTtoGenerateERDsforSQL.aspx</guid>
            <pubDate>Fri, 05 Jan 2007 05:16:56 GMT</pubDate>
            <comments>http://ridgway.co.za/archive/2007/01/05/GraphVizTtoGenerateERDsforSQL.aspx#feedback</comments>
            <slash:comments>6</slash:comments>
            <wfw:commentRss>http://ridgway.co.za/comments/commentRss/176.aspx</wfw:commentRss>
        </item>
        <item>
            <title>A SQL 2005 Managed CSV Split UDF</title>
            <link>http://ridgway.co.za/archive/2006/01/17/asql2005managedcsvsplitudf.aspx</link>
            <description>This morning I decided to delve into the wonders of managed code running in SQL 2005.  To me it was obvious that the best candidate for this technology was a function that split a comma separated list of values and returned a table.  I've used a variety of different approaches to solve this problem, ranging from a TSQL UDF that split the values to a CHARINDEX and LIKE trick.  I was really hoping that a managed UDF would be orders of magnitude faster than a TSQL implementation of this sort.&lt;br /&gt;
&lt;br /&gt;
So I created a SQL Server Project in Visual Studio 2005 and created the following class:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="code"&gt;&lt;font color="blue"&gt;using &lt;/font&gt;&lt;font color="black"&gt;System&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
using &lt;/font&gt;&lt;font color="black"&gt;Microsoft.SqlServer.Server&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
using &lt;/font&gt;&lt;font color="black"&gt;System.Collections&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
&lt;br /&gt;
public &lt;/font&gt;&lt;font color="black"&gt;partial &lt;/font&gt;&lt;font color="blue"&gt;class &lt;/font&gt;&lt;font color="black"&gt;UserDefinedFunctions&lt;br /&gt;
{&lt;br /&gt;
    [SqlFunction(FillRowMethodName &lt;/font&gt;&lt;font color="blue"&gt;= &lt;/font&gt;&lt;font color="#808080"&gt;"FillVarcharRow"&lt;/font&gt;&lt;font color="black"&gt;, TableDefinition &lt;/font&gt;&lt;font color="blue"&gt;= &lt;/font&gt;&lt;font color="#808080"&gt;"value nvarchar(200)"&lt;/font&gt;&lt;font color="black"&gt;)]&lt;br /&gt;
    &lt;/font&gt;&lt;font color="blue"&gt;public static &lt;/font&gt;&lt;font color="black"&gt;IEnumerable GetCsvVarcharTable(&lt;/font&gt;&lt;font color="blue"&gt;string &lt;/font&gt;&lt;font color="black"&gt;commaSeparatedList)&lt;br /&gt;
    {&lt;br /&gt;
        &lt;/font&gt;&lt;font color="blue"&gt;return &lt;/font&gt;&lt;font color="black"&gt;commaSeparatedList.Split(&lt;/font&gt;&lt;font color="blue"&gt;new char&lt;/font&gt;&lt;font color="black"&gt;[] { &lt;/font&gt;&lt;font color="#808080"&gt;',' &lt;/font&gt;&lt;font color="black"&gt;})&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
    &lt;/font&gt;&lt;font color="black"&gt;}&lt;br /&gt;
&lt;br /&gt;
    &lt;/font&gt;&lt;font color="blue"&gt;public static void &lt;/font&gt;&lt;font color="black"&gt;FillVarcharRow(&lt;/font&gt;&lt;font color="blue"&gt;object &lt;/font&gt;&lt;font color="black"&gt;row, &lt;/font&gt;&lt;font color="blue"&gt;out string value&lt;/font&gt;&lt;font color="black"&gt;)&lt;br /&gt;
    {&lt;br /&gt;
        &lt;/font&gt;&lt;font color="blue"&gt;value = &lt;/font&gt;&lt;font color="black"&gt;(&lt;/font&gt;&lt;font color="blue"&gt;string&lt;/font&gt;&lt;font color="black"&gt;)row&lt;/font&gt;&lt;font color="blue"&gt;;&lt;br /&gt;
    &lt;/font&gt;&lt;font color="black"&gt;}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;/font&gt; &lt;/div&gt;
&lt;br /&gt;
After deploying it I tried to execute the UDF only to find out that CLR extensions are disabled by defualt.  The following script got me back on my way:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="code"&gt;&lt;font color="black"&gt;sp_configure &lt;/font&gt;&lt;font color="#808080"&gt;'clr enabled'&lt;/font&gt;&lt;font color="black"&gt;, &lt;/font&gt;&lt;font color="maroon"&gt;1&lt;br /&gt;
&lt;/font&gt;&lt;font color="blue"&gt;GO&lt;br /&gt;
RECONFIGURE&lt;br /&gt;
GO&lt;/font&gt;  &lt;/div&gt;
&lt;br /&gt;
I plan on taking a closer look at the performance implications of using the managed UDF and I will update the post as more information becomes available.&lt;br /&gt;
&lt;img src="http://ridgway.co.za/aggbug/160.aspx" width="1" height="1" /&gt;</description>
            <guid>http://ridgway.co.za/archive/2006/01/17/asql2005managedcsvsplitudf.aspx</guid>
            <pubDate>Tue, 17 Jan 2006 03:02:03 GMT</pubDate>
            <comments>http://ridgway.co.za/archive/2006/01/17/asql2005managedcsvsplitudf.aspx#feedback</comments>
            <wfw:commentRss>http://ridgway.co.za/comments/commentRss/160.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>