<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>richard-slater.co.uk &#187; Sys. Admin.</title>
	<atom:link href="http://www.richard-slater.co.uk/archives/category/sys-admin/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.richard-slater.co.uk</link>
	<description>Jesus, Life, Programming and Systems Administration</description>
	<lastBuildDate>Mon, 02 Jan 2012 10:07:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Listing Table Sizes</title>
		<link>http://www.richard-slater.co.uk/archives/2010/12/24/listing-table-sizes/</link>
		<comments>http://www.richard-slater.co.uk/archives/2010/12/24/listing-table-sizes/#comments</comments>
		<pubDate>Fri, 24 Dec 2010 10:20:09 +0000</pubDate>
		<dc:creator>Richard Slater</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Sys. Admin.]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://www.richard-slater.co.uk/?p=867</guid>
		<description><![CDATA[Databases are a pain in the neck to look after, poorly designed models and processes that don&#8217;t remove temporary data can cause a database to grow in size. A database that is allowed to grow large beyond its requirements becomes a burden on the nightly backup, takes longer to restore in the event of a recovery scenario [...]]]></description>
			<content:encoded><![CDATA[<p>Databases are a pain in the neck to look after, poorly designed models and processes that don&#8217;t remove temporary data can cause a database to grow in size. A database that is allowed to grow large beyond its requirements becomes a burden on the nightly backup, takes longer to restore in the event of a recovery scenario and slows down the development process by preventing developers from testing things out on &#8220;live&#8221; data.</p>
<p>More often than not I have found that the problem lies with log or analytic tables sometimes this information is liberally logged (which it should be) and then totally ignored without a thought for trimming the data on a regular basis.</p>
<p>SQL Server Management Studio provides a way of looking at the storage usage of tables individually from the properties context menu item of the table.</p>
<p style="text-align: center;"><a href="http://www.richard-slater.co.uk/wp-content/uploads/2010/11/SSMSStorageProperties.png"><img class="aligncenter size-full wp-image-868" title="SSMS Storage Properties" src="http://www.richard-slater.co.uk/wp-content/uploads/2010/11/SSMSStorageProperties.png" alt="SSMS Storage Properties" width="394" height="354" /></a></p>
<p>In large databases this can be laborious, I found <a href="http://www.cryer.co.uk/brian/sqlserver/howto_list_table_sizes.htm">a script</a> that will collect this information and present it as a table. I have adapted it a little so that I can see the total size of the table and sort by each column to drill down to the problem tables.</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SET</span> NOCOUNT <span style="color: #993333; font-weight: bold;">ON</span>
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> #spaceused <span style="color: #66cc66;">&#40;</span>
  name nvarchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">120</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  <span style="color: #993333; font-weight: bold;">ROWS</span> <span style="color: #993333; font-weight: bold;">CHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">11</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  reserved <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">18</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  <span style="color: #993333; font-weight: bold;">DATA</span> <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">18</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  index_size <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">18</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  unused <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">18</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #993333; font-weight: bold;">DECLARE</span> TablesFromSysObjects CURSOR <span style="color: #993333; font-weight: bold;">FOR</span>
  <span style="color: #993333; font-weight: bold;">SELECT</span> name
  <span style="color: #993333; font-weight: bold;">FROM</span> sysobjects <span style="color: #993333; font-weight: bold;">WHERE</span> <span style="color: #993333; font-weight: bold;">TYPE</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">'U'</span>
  <span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> name <span style="color: #993333; font-weight: bold;">ASC</span>
&nbsp;
<span style="color: #993333; font-weight: bold;">OPEN</span> TablesFromSysObjects
<span style="color: #993333; font-weight: bold;">DECLARE</span> @<span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">128</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
FETCH <span style="color: #993333; font-weight: bold;">NEXT</span> <span style="color: #993333; font-weight: bold;">FROM</span> TablesFromSysObjects <span style="color: #993333; font-weight: bold;">INTO</span> @<span style="color: #993333; font-weight: bold;">TABLE</span>
&nbsp;
WHILE @@FETCH_STATUS <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span>
<span style="color: #993333; font-weight: bold;">BEGIN</span>
  <span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> #spaceused <span style="color: #993333; font-weight: bold;">EXEC</span> sp_spaceused @<span style="color: #993333; font-weight: bold;">TABLE</span>
  FETCH <span style="color: #993333; font-weight: bold;">NEXT</span> <span style="color: #993333; font-weight: bold;">FROM</span> TablesFromSysObjects <span style="color: #993333; font-weight: bold;">INTO</span> @<span style="color: #993333; font-weight: bold;">TABLE</span>
<span style="color: #993333; font-weight: bold;">END</span>
&nbsp;
CLOSE TablesFromSysObjects
DEALLOCATE TablesFromSysObjects 
&nbsp;
<span style="color: #993333; font-weight: bold;">SELECT</span>	name <span style="color: #993333; font-weight: bold;">AS</span> TableName<span style="color: #66cc66;">,</span>
		<span style="color: #993333; font-weight: bold;">ROWS</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #993333; font-weight: bold;">ROWS</span><span style="color: #66cc66;">,</span>
		<span style="color: #993333; font-weight: bold;">CAST</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">LEFT</span><span style="color: #66cc66;">&#40;</span>reserved<span style="color: #66cc66;">,</span> LEN<span style="color: #66cc66;">&#40;</span>reserved<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #993333; font-weight: bold;">INT</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> Reserved<span style="color: #66cc66;">,</span>
		<span style="color: #993333; font-weight: bold;">CAST</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">LEFT</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATA</span><span style="color: #66cc66;">,</span> LEN<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATA</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #993333; font-weight: bold;">INT</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #993333; font-weight: bold;">DATA</span><span style="color: #66cc66;">,</span>
		<span style="color: #993333; font-weight: bold;">CAST</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">LEFT</span><span style="color: #66cc66;">&#40;</span>index_size<span style="color: #66cc66;">,</span> LEN<span style="color: #66cc66;">&#40;</span>index_size<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #993333; font-weight: bold;">INT</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> IndexSize<span style="color: #66cc66;">,</span>
		<span style="color: #993333; font-weight: bold;">CAST</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">LEFT</span><span style="color: #66cc66;">&#40;</span>unused<span style="color: #66cc66;">,</span> LEN<span style="color: #66cc66;">&#40;</span>unused<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #993333; font-weight: bold;">INT</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> Unused<span style="color: #66cc66;">,</span>
		<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">CAST</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">LEFT</span><span style="color: #66cc66;">&#40;</span>reserved<span style="color: #66cc66;">,</span> LEN<span style="color: #66cc66;">&#40;</span>reserved<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #993333; font-weight: bold;">INT</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">CAST</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">LEFT</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATA</span><span style="color: #66cc66;">,</span> LEN<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DATA</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #993333; font-weight: bold;">INT</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">CAST</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">LEFT</span><span style="color: #66cc66;">&#40;</span>index_size<span style="color: #66cc66;">,</span> LEN<span style="color: #66cc66;">&#40;</span>index_size<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #993333; font-weight: bold;">INT</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">CAST</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">LEFT</span><span style="color: #66cc66;">&#40;</span>unused<span style="color: #66cc66;">,</span> LEN<span style="color: #66cc66;">&#40;</span>unused<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #993333; font-weight: bold;">INT</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> Total
<span style="color: #993333; font-weight: bold;">FROM</span> #spaceused
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> Total <span style="color: #993333; font-weight: bold;">DESC</span>
<span style="color: #993333; font-weight: bold;">DROP</span> <span style="color: #993333; font-weight: bold;">TABLE</span> #spaceused</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.richard-slater.co.uk/archives/2010/12/24/listing-table-sizes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ordinance Survey OpenData (Part 3 &#8211; Cleaning Up)</title>
		<link>http://www.richard-slater.co.uk/archives/2010/12/17/ordinance-survey-opendata-part-3-cleaning-up/</link>
		<comments>http://www.richard-slater.co.uk/archives/2010/12/17/ordinance-survey-opendata-part-3-cleaning-up/#comments</comments>
		<pubDate>Fri, 17 Dec 2010 15:55:38 +0000</pubDate>
		<dc:creator>Richard Slater</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Sys. Admin.]]></category>
		<category><![CDATA[OpenData]]></category>
		<category><![CDATA[Ordinance Survey]]></category>
		<category><![CDATA[OS]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://www.richard-slater.co.uk/?p=882</guid>
		<description><![CDATA[If you look through the schema of the table we imported in Part 2 there are a number of unused fields and some of the data appears to be missing. Cleaning up the Schema You can go right ahead and remove the fields that start with &#8220;Unused&#8221; as far as I can tell the full [...]]]></description>
			<content:encoded><![CDATA[<p>If you look through the schema of the table we imported in <a href="http://www.richard-slater.co.uk/archives/2010/12/10/ordinance-survey-opendata-part-2-importing-the-data/">Part 2</a> there are a number of unused fields and some of the data appears to be missing.</p>
<h2>Cleaning up the Schema</h2>
<ol>
<li>You can go right ahead and remove the fields that start with &#8220;Unused&#8221; as far as I can tell the full version of Code-Point uses these fields.</li>
<li>Remove the nullable attributes from all of the fields, this will prevent us from doing something silly at a later date, and will avoid Object Relational Mappers such as Entity Framework from creating nullable data types.</li>
<li>Many of the fields contain codes not data itself but codes that describe other data, so lets prepend code on the end of those fields for the time being.</li>
</ol>
<h2>Cleaning up the Data</h2>
<p>The quality column in Code-Point Open describes the source and reliability of the data, it ranges from the most accurate 10 through to no data 90, when building a system around this data you need to decide at what data is important to your use case. The following query will give you an idea of the quality of the dataset as a whole, I have annotated it based upon the <a href="http://www.ordnancesurvey.co.uk/oswebsite/products/code-point-open/">OS Code-Point documentation</a>.</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> Quality<span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">COUNT</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">*</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #993333; font-weight: bold;">COUNT</span>
<span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #66cc66;">&#91;</span>OSOpenData<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">.</span><span style="color: #66cc66;">&#91;</span>dbo<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">.</span><span style="color: #66cc66;">&#91;</span>CodePointOpenCombined<span style="color: #66cc66;">&#93;</span>
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> Quality
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> Quality</pre></div></div>

<table>
<tbody>
<tr>
<th>Quality</th>
<th>Count</th>
<th>Description</th>
</tr>
<tr>
<td>10</td>
<td>1683975</td>
<td>Within the building of the matched address closest to the postcode mean determined automatically by Ordnance Survey.</td>
</tr>
<tr>
<td>20</td>
<td>73</td>
<td>As above, but determined to visual inspection by GROS (General Register Office for Scotland).</td>
</tr>
<tr>
<td>30</td>
<td>1086</td>
<td>Approximate to within 50 m of true position.</td>
</tr>
<tr>
<td>40</td>
<td>52</td>
<td>The mean of the positions of addresses previously matched in ADDRESS-POINT but which have subsequently been deleted or recoded.</td>
</tr>
<tr>
<td>50</td>
<td>4395</td>
<td>Estimated position based on surrounding postcode coordinates, usually to 100 m resolution, but 10 min Scotland.</td>
</tr>
<tr>
<td>60</td>
<td>93</td>
<td>Postcode sector mean (direct copy from ADDRESS-POINT).</td>
</tr>
<tr>
<td>90</td>
<td>6361</td>
<td>No coordinates available.</td>
</tr>
</tbody>
</table>
<p>For my purposes I want to use the coordinate data stored in the Eastings and Northings columns, which makes postcodes with no data useless to me, I can remove these with the following SQL script:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">DELETE</span> <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #66cc66;">&#91;</span>CodePointOpenCombined<span style="color: #66cc66;">&#93;</span>
<span style="color: #993333; font-weight: bold;">WHERE</span> <span style="color: #66cc66;">&#91;</span>Quality<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">90</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.richard-slater.co.uk/archives/2010/12/17/ordinance-survey-opendata-part-3-cleaning-up/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ordinance Survey OpenData (Part 2 &#8211; Importing The Data)</title>
		<link>http://www.richard-slater.co.uk/archives/2010/12/10/ordinance-survey-opendata-part-2-importing-the-data/</link>
		<comments>http://www.richard-slater.co.uk/archives/2010/12/10/ordinance-survey-opendata-part-2-importing-the-data/#comments</comments>
		<pubDate>Fri, 10 Dec 2010 14:26:53 +0000</pubDate>
		<dc:creator>Richard Slater</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Sys. Admin.]]></category>
		<category><![CDATA[OpenData]]></category>
		<category><![CDATA[Ordinance Survey]]></category>
		<category><![CDATA[OS]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://www.richard-slater.co.uk/?p=878</guid>
		<description><![CDATA[All of the data is in different files; SSIS is capable of extracting data from multiple files however for the purposes of this article I am going to stick to the Import Export Wizard. To combine all of the files into one (big) file a quick switch to the command prompt is required: type data\*.csv [...]]]></description>
			<content:encoded><![CDATA[<p>All of the data is in different files; SSIS is capable of extracting data from multiple files however for the purposes of this article I am going to stick to the Import Export Wizard.</p>
<p>To combine all of the files into one (big) file a quick switch to the command prompt is required:</p>
<pre>type data\*.csv &gt; .\CodePointOpenCombined.csv</pre>
<p>Because none of the data files have headers this works fine, if they did have headers some work would be needed to strip those out.</p>
<p>Create a new database in SQL Server then follow these steps:</p>
<ol>
<li>Right Click the Database select &#8220;Tasks&#8221; &#8211; &#8220;Import Data&#8221;.</li>
<li>In the Data Source step change the drop down to &#8220;Flat File Source&#8221;.</li>
<li>Select the combined file we created above (you may have to change the filter).</li>
<li>Check the Columns page if Quotation Marks (&#8220;) appear in some of the columns change the Text qualifier field on the General Page to a &#8220;.</li>
<li>On the Advanced page click Suggest Types.</li>
<li>Set the number of rows to 1000 (the maximum), then click OK.</li>
<li>Go through each column and update the name and DataType to match those we discovered in the <a href="http://www.richard-slater.co.uk/archives/2010/12/03/ordinance-survey-opendata-part1-schema-scanne/">previous post</a>.</li>
<li>Check the correct database and table are selected on the next two steps.</li>
<li>Click Next then Next again, then check over the data type mappings.</li>
<li>Click Next then ensure Run immediately is checked then click finish.</li>
<li>All being well, all of the data will be imported successfully.</li>
</ol>
<p>If there are problems importing the data you can go back and make changes to the configuration, typically the issue is incorrect data types (too small) or incorrect text delimiters.</p>
<p>You may be asking why we went to tall that trouble, and time, only to let the Import Data Wizard suggest the data types. The reason I wrote the script was the wizard is limited to checking the first 1,000 lines; even if you set the value to 2,000,000 it will default down to 1000 after you move your focus away.</p>
<p>The result being if your data is naturally sorted on a specific column as some of the Ordinance Survey data appears to be the import will fail. Running the schema scanner allows you to scan through all of the data so that you can modify the suggested data types to match the maximum values.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.richard-slater.co.uk/archives/2010/12/10/ordinance-survey-opendata-part-2-importing-the-data/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ordinance Survey OpenData (Part 1 &#8211; Schema Scanner)</title>
		<link>http://www.richard-slater.co.uk/archives/2010/12/03/ordinance-survey-opendata-part1-schema-scanne/</link>
		<comments>http://www.richard-slater.co.uk/archives/2010/12/03/ordinance-survey-opendata-part1-schema-scanne/#comments</comments>
		<pubDate>Fri, 03 Dec 2010 15:49:32 +0000</pubDate>
		<dc:creator>Richard Slater</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Sys. Admin.]]></category>
		<category><![CDATA[Data]]></category>
		<category><![CDATA[OpenData]]></category>
		<category><![CDATA[Ordinance Survey]]></category>
		<category><![CDATA[OS]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://www.richard-slater.co.uk/?p=873</guid>
		<description><![CDATA[In April 2010 the Ordinance Survey released certain parts of their data under special licence which allows for commercial use without cost. All the types of data made available are outside the scope of this post although I hope that the techniques described could be applied to any data set not limited to Ordinance Survey [...]]]></description>
			<content:encoded><![CDATA[<p>In April 2010 the Ordinance Survey released certain parts of their data under special licence which allows for commercial use without cost. All the types of data made available are outside the scope of this post although I hope that the techniques described could be applied to any data set not limited to Ordinance Survey data.</p>
<p>In this post I am going to look at <a href="http://www.ordnancesurvey.co.uk/oswebsite/products/code-point-open/">Code-Point Open</a>, a list of all UK postcodes with their corresponding spatial positions. Unlike many other OS OpenData downloads the ZIP file does not contain the User Guide or the Schema Data, this can be found on the website, I spent a good 10 minutes searching for this data.</p>
<p>The term for what we are doing in this post is Extract-Transform -Load (ETL), a process in which we take data in one format and covert it for use in another format. Generally ETL is used to take a flat file format and load it for use in a relational database, although technically any format or database could be used. SQL Server offers two built-in mechanisms to perform ETL; the &#8220;Import Export Wizard&#8221; and SQL Server Integration Services (SSIS). The &#8220;Import Export Wizard&#8221; actually creates a SSIS package in the background and is available to all versions of SQL Server, SSIS  is not available in SQL Express.</p>
<p>Before we create a table in a SQL Server Database we need to know something about the data we are importing, the documentation for Code-Point Open tells us the data contains the following fields:</p>
<p><strong>Postcode</strong>, <strong>Quality</strong>, Unused1, Unused2, Unused3, Unused4, Unused5, Unused6, Unused7, Unused8, <strong>Eastings</strong>, <strong>Northings</strong>, <strong>CountryCode</strong>, <strong>RegionalHealthAuthority</strong>, <strong>HealthAuthority</strong>, <strong>AdminCounty</strong>, <strong>AdminDistrict</strong>, <strong>AdminWard</strong>, Unused10</p>
<p>A number of the fields are not used, the fields and the dummy data held within them will be weeded out at a later date, we know the fields but we don&#8217;t know the format of the data it contains, it could be numeric, strings, decimals, telephone numbers? I created a PowerShell script which scans through all of these files to work out what type of field it is and the range of data held within it, be warned it will take a few hours to run!</p>

<div class="wp_syntax"><div class="code"><pre class="powershell" style="font-family:monospace;"><span style="color: #008000;"># Schema Scanner v1.0</span>
<span style="color: #008000;"># ©2010 Richard Slater</span>
&nbsp;
<span style="color: #008000;"># Create an empty hash table</span>
<span style="color: #800080;">$columns</span> <span style="color: pink;">=</span> <span style="color: pink;">@</span><span style="color: #000000;">&#123;</span><span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #008000;"># Loop through every file that matches this pattern</span>
<span style="color: #0000FF;">foreach</span> <span style="color: #000000;">&#40;</span><span style="color: #800080;">$file</span> <span style="color: #0000FF;">in</span> <span style="color: #008080; font-weight: bold;">Get-ChildItem</span> <span style="color: #008080; font-style: italic;">-Path</span> <span style="color: #800000;">&quot;D:\OSOpenData\Code-Point Open\data\ze.csv&quot;</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
	<span style="color: #008080; font-weight: bold;">Write-Host</span> <span style="color: #800000;">&quot;Processing $file&quot;</span>
&nbsp;
	<span style="color: #008000;"># PowerShell Import-Csv cmdlet is pretty powerful, but if there is no header row you must feed it in</span>
	<span style="color: #800080;">$PostCodeData</span> <span style="color: pink;">=</span> <span style="color: #008080; font-weight: bold;">Import-Csv</span> <span style="color: #800080;">$file</span> <span style="color: pink;">-</span>Header <span style="color: #800000;">&quot;Postcode&quot;</span><span style="color: pink;">,</span><span style="color: #800000;">&quot;Quality&quot;</span><span style="color: pink;">,</span><span style="color: #800000;">&quot;Unused1&quot;</span><span style="color: pink;">,</span><span style="color: #800000;">&quot;Unused2&quot;</span><span style="color: pink;">,</span><span style="color: #800000;">&quot;Unused3&quot;</span><span style="color: pink;">,</span><span style="color: #800000;">&quot;Unused4&quot;</span><span style="color: pink;">,</span><span style="color: #800000;">&quot;Unused5&quot;</span><span style="color: pink;">,</span><span style="color: #800000;">&quot;Unused6&quot;</span><span style="color: pink;">,</span><span style="color: #800000;">&quot;Unused7&quot;</span><span style="color: pink;">,</span><span style="color: #800000;">&quot;Unused8&quot;</span><span style="color: pink;">,</span><span style="color: #800000;">&quot;Eastings&quot;</span><span style="color: pink;">,</span><span style="color: #800000;">&quot;Northings&quot;</span><span style="color: pink;">,</span><span style="color: #800000;">&quot;CountryCode&quot;</span><span style="color: pink;">,</span><span style="color: #800000;">&quot;RegionalHealthAuthority&quot;</span><span style="color: pink;">,</span><span style="color: #800000;">&quot;HealthAuthority&quot;</span><span style="color: pink;">,</span><span style="color: #800000;">&quot;AdminCounty&quot;</span><span style="color: pink;">,</span><span style="color: #800000;">&quot;AdminDistrict&quot;</span><span style="color: pink;">,</span><span style="color: #800000;">&quot;AdminWard&quot;</span><span style="color: pink;">,</span><span style="color: #800000;">&quot;Unused10&quot;</span>
&nbsp;
	<span style="color: #008000;"># Go through each row in the file</span>
	<span style="color: #0000FF;">foreach</span><span style="color: #000000;">&#40;</span><span style="color: #800080;">$row</span> <span style="color: #0000FF;">in</span> <span style="color: #800080;">$PostCodeData</span><span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
		<span style="color: #008000;"># Go through each column in the row</span>
		<span style="color: #0000FF;">foreach</span> <span style="color: #000000;">&#40;</span><span style="color: #800080;">$attr</span> <span style="color: #0000FF;">in</span> <span style="color: #000000;">&#40;</span><span style="color: #008080; font-weight: bold;">Get-Member</span> <span style="color: #008080; font-style: italic;">-InputObject</span> <span style="color: #800080;">$PostCodeData</span><span style="color: #000000;">&#91;</span><span style="color: #804000;">0</span><span style="color: #000000;">&#93;</span> <span style="color: #008080; font-style: italic;">-MemberType</span> NoteProperty<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
		<span style="color: #000000;">&#123;</span>
			<span style="color: #800080;">$key</span> <span style="color: pink;">=</span> <span style="color: #800080;">$attr</span>.Name
&nbsp;
			<span style="color: #008000;"># Ignore unused columns</span>
			<span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #800080;">$key</span>.StartsWith<span style="color: #000000;">&#40;</span><span style="color: #800000;">&quot;Unused&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
				<span style="color: #000000;">&#123;</span> <span style="color: #0000FF;">continue</span> <span style="color: #000000;">&#125;</span>
&nbsp;
			<span style="color: #008000;"># Construct an object to store the meta data, store it in the hash table to retreive next loop</span>
			<span style="color: #800080;">$column</span> <span style="color: pink;">=</span> <span style="color: #008080; font-weight: bold;">New-Object</span> PSObject
			<span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: pink;">!</span><span style="color: #800080;">$columns</span>.ContainsKey<span style="color: #000000;">&#40;</span><span style="color: #800080;">$key</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
			<span style="color: #000000;">&#123;</span>
				<span style="color: #800080;">$column</span> <span style="color: pink;">|</span> <span style="color: #008080; font-weight: bold;">Add-Member</span> <span style="color: pink;">-</span><span style="color: #008080; font-weight: bold;">Type</span> NoteProperty <span style="color: #008080; font-style: italic;">-Name</span> StringLength <span style="color: #008080; font-style: italic;">-Value</span> <span style="color: #804000;">0</span>
				<span style="color: #800080;">$column</span> <span style="color: pink;">|</span> <span style="color: #008080; font-weight: bold;">Add-Member</span> <span style="color: pink;">-</span><span style="color: #008080; font-weight: bold;">Type</span> NoteProperty <span style="color: #008080; font-style: italic;">-Name</span> MaxValue <span style="color: #008080; font-style: italic;">-Value</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#91;</span>System.Int32<span style="color: #000000;">&#93;</span>::MinValue<span style="color: #000000;">&#41;</span>
				<span style="color: #800080;">$column</span> <span style="color: pink;">|</span> <span style="color: #008080; font-weight: bold;">Add-Member</span> <span style="color: pink;">-</span><span style="color: #008080; font-weight: bold;">Type</span> NoteProperty <span style="color: #008080; font-style: italic;">-Name</span> MinValue <span style="color: #008080; font-style: italic;">-Value</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#91;</span>System.Int32<span style="color: #000000;">&#93;</span>::MaxValue<span style="color: #000000;">&#41;</span>
				<span style="color: #800080;">$columns</span>.Add<span style="color: #000000;">&#40;</span><span style="color: #800080;">$key</span><span style="color: pink;">,</span> <span style="color: #800080;">$column</span><span style="color: #000000;">&#41;</span>
			<span style="color: #000000;">&#125;</span>
			<span style="color: #0000FF;">else</span>
				<span style="color: #000000;">&#123;</span> <span style="color: #800080;">$column</span> <span style="color: pink;">=</span> <span style="color: #800080;">$columns</span>.Get_Item<span style="color: #000000;">&#40;</span><span style="color: #800080;">$key</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#125;</span>
&nbsp;
			<span style="color: #800080;">$isInt</span> <span style="color: pink;">=</span> <span style="color: #800080;">$false</span>
			<span style="color: #800080;">$value</span> <span style="color: pink;">=</span> <span style="color: #804000;">0</span>;
&nbsp;
			<span style="color: #008000;"># Work out if this is an integer type</span>
			<span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#91;</span>System.Int32<span style="color: #000000;">&#93;</span>::TryParse<span style="color: #000000;">&#40;</span><span style="color: #800080;">$row</span>.<span style="color: #000000;">&#40;</span><span style="color: #800080;">$key</span><span style="color: #000000;">&#41;</span><span style="color: pink;">,</span> <span style="color: #000000;">&#91;</span><span style="color: #008080;">ref</span><span style="color: #000000;">&#93;</span> <span style="color: #800080;">$value</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
            	<span style="color: #000000;">&#123;</span> <span style="color: #800080;">$isInt</span> <span style="color: pink;">=</span> <span style="color: #800080;">$true</span> <span style="color: #000000;">&#125;</span>
&nbsp;
			<span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: pink;">!</span><span style="color: #800080;">$isInt</span><span style="color: #000000;">&#41;</span>
            <span style="color: #000000;">&#123;</span>
				<span style="color: #008000;"># it is not an integer how many characters is the string</span>
            	<span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span><span style="color: #800080;">$row</span>.<span style="color: #000000;">&#40;</span><span style="color: #800080;">$key</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>.Length <span style="color: #FF0000;">-gt</span> <span style="color: #800080;">$column</span>.StringLength<span style="color: #000000;">&#41;</span>
                	<span style="color: #000000;">&#123;</span> <span style="color: #800080;">$column</span>.StringLength <span style="color: pink;">=</span> <span style="color: #000000;">&#40;</span><span style="color: #800080;">$row</span>.<span style="color: #000000;">&#40;</span><span style="color: #800080;">$key</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>.Length <span style="color: #000000;">&#125;</span>
&nbsp;
				<span style="color: #0000FF;">continue</span>
            <span style="color: #000000;">&#125;</span>
&nbsp;
			<span style="color: #008000;"># it is an integer start working out the maximum and minimum values</span>
			<span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span> <span style="color: #800080;">$value</span> <span style="color: #FF0000;">-gt</span> <span style="color: #800080;">$column</span>.MaxValue <span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #800080;">$column</span>.MaxValue <span style="color: pink;">=</span> <span style="color: #800080;">$value</span> <span style="color: #000000;">&#125;</span>
			<span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span> <span style="color: #800080;">$value</span> <span style="color: #FF0000;">-lt</span> <span style="color: #800080;">$column</span>.MinValue <span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #800080;">$column</span>.MinValue <span style="color: pink;">=</span> <span style="color: #800080;">$value</span> <span style="color: #000000;">&#125;</span>
&nbsp;
			<span style="color: #800080;">$columns</span>.Set_Item<span style="color: #000000;">&#40;</span><span style="color: #800080;">$key</span><span style="color: pink;">,</span> <span style="color: #800080;">$column</span><span style="color: #000000;">&#41;</span>
		<span style="color: #000000;">&#125;</span>
	<span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #008000;"># Print a report of all of the fields</span>
<span style="color: #0000FF;">foreach</span> <span style="color: #000000;">&#40;</span><span style="color: #800080;">$field</span> <span style="color: #0000FF;">in</span> <span style="color: #800080;">$columns</span>.Keys<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
	<span style="color: #800080;">$stringLength</span> <span style="color: pink;">=</span> <span style="color: #800080;">$columns</span><span style="color: #000000;">&#91;</span><span style="color: #800080;">$field</span><span style="color: #000000;">&#93;</span>.StringLength
	<span style="color: #800080;">$numericMax</span> <span style="color: pink;">=</span> <span style="color: #800080;">$columns</span><span style="color: #000000;">&#91;</span><span style="color: #800080;">$field</span><span style="color: #000000;">&#93;</span>.MaxValue
	<span style="color: #800080;">$numericMin</span> <span style="color: pink;">=</span> <span style="color: #800080;">$columns</span><span style="color: #000000;">&#91;</span><span style="color: #800080;">$field</span><span style="color: #000000;">&#93;</span>.MinValue
&nbsp;
	<span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #800080;">$stringLength</span> <span style="color: #FF0000;">-gt</span> <span style="color: #804000;">0</span><span style="color: #000000;">&#41;</span>
	<span style="color: #000000;">&#123;</span>
		<span style="color: #008080; font-weight: bold;">Write-Host</span> <span style="color: #800000;">&quot;$field (String) : Length =&quot;</span> <span style="color: #800080;">$columns</span><span style="color: #000000;">&#91;</span><span style="color: #800080;">$field</span><span style="color: #000000;">&#93;</span>.StringLength
	<span style="color: #000000;">&#125;</span>
	<span style="color: #0000FF;">elseif</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span><span style="color: #800080;">$numericMax</span> <span style="color: #FF0000;">-gt</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#91;</span>System.Int32<span style="color: #000000;">&#93;</span>::MinValue<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span> <span style="color: #FF0000;">-and</span> <span style="color: #000000;">&#40;</span><span style="color: #800080;">$numericMin</span> <span style="color: #FF0000;">-lt</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#91;</span>System.Int32<span style="color: #000000;">&#93;</span>::MaxValue<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
	<span style="color: #000000;">&#123;</span>
		<span style="color: #008080; font-weight: bold;">Write-Host</span> <span style="color: #800000;">&quot;$field (Numeric) : MaxValue =&quot;</span> <span style="color: #800080;">$numericMax</span> <span style="color: #800000;">&quot;, MinValue =&quot;</span> <span style="color: #800080;">$numericMin</span>
	<span style="color: #000000;">&#125;</span>
	<span style="color: #0000FF;">else</span>
	<span style="color: #000000;">&#123;</span>
		<span style="color: #008080; font-weight: bold;">Write-Host</span> <span style="color: #800000;">&quot;$field (Empty)&quot;</span>
	<span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>The output from the script should give you enough information to construct a nice tight schema to import the data:</p>
<pre>AdminWard (String) : Length = 2
AdminDistrict (String) : Length = 2
AdminCounty (Numeric) : MinValue = 0 , MaxValue = 47
Quality (Numeric) :  MinValue = 10 , MaxValue = 90
RegionalHealthAuthority (String) : Length = 3
Postcode (String) : Length = 7
Eastings (Numeric) : MinValue = 0 , MaxValue = 655448
Northings (Numeric) : MinValue = 0 , MaxValue = 1213660
CountryCode (Numeric) : = 64 ,  MaxValue   = 220
HealthAuthority (String) : Length = 3</pre>
<p>In a future post I am going to take it to the next stage; create a table and complete the import with the Import Export Wizard. I would also like to improve the performance of the schema scanner by converting the code into C#.</p>
<p><a href="http://www.richard-slater.co.uk/wp-content/uploads/2010/12/SchemaScanner.zip">SchemaScanner</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.richard-slater.co.uk/archives/2010/12/03/ordinance-survey-opendata-part1-schema-scanne/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Elevated Command Prompt</title>
		<link>http://www.richard-slater.co.uk/archives/2010/10/07/elevated-command-prompt/</link>
		<comments>http://www.richard-slater.co.uk/archives/2010/10/07/elevated-command-prompt/#comments</comments>
		<pubDate>Thu, 07 Oct 2010 12:32:40 +0000</pubDate>
		<dc:creator>Richard Slater</dc:creator>
				<category><![CDATA[Sys. Admin.]]></category>
		<category><![CDATA[Command Prompt]]></category>
		<category><![CDATA[Elevated]]></category>
		<category><![CDATA[Run as Administrator]]></category>

		<guid isPermaLink="false">http://www.richard-slater.co.uk/?p=827</guid>
		<description><![CDATA[I explained how to get an elevated Command Prompt to perform system tasks in the comments of my post about setting the MTU in Windows 7, I am writing the up a bit clearer and linking it from that post. In Vista and Windows 7 applications don&#8217;t automatically get administrator privilege, they either need to [...]]]></description>
			<content:encoded><![CDATA[<p><em>I explained how to get an elevated Command Prompt to perform system tasks in the comments of my post about setting the <a href="http://www.richard-slater.co.uk/archives/2009/10/23/change-your-mtu-under-vista-or-windows-7/">MTU in Windows 7</a>, I am writing the up a bit clearer and linking it from that post.</em></p>
<p>In Vista and Windows 7 applications don&#8217;t automatically get administrator privilege, they either need to request it or the user needs to explicitly start the application as an Administrator. The way to do this with the Command Prompt is as follows:</p>
<ol>
<li>Press the &#8220;Start&#8221; button.</li>
<li>Type &#8220;Command&#8221;.</li>
<li>&#8220;Command Prompt&#8221; will be shown in the search results.<br />
<a href="http://www.richard-slater.co.uk/wp-content/uploads/2010/10/SearchStartForCommandPrompt.png"><img class="size-medium wp-image-828 alignnone" title="SearchStartForCommandPrompt" src="http://www.richard-slater.co.uk/wp-content/uploads/2010/10/SearchStartForCommandPrompt-221x300.png" alt="" width="221" height="300" /></a></li>
<li>Right Click &#8220;Command Prompt&#8221; and select &#8220;Run as Administrator&#8221; (it will have a blue and yellow shield beside it).<br />
<a href="http://www.richard-slater.co.uk/wp-content/uploads/2010/10/RunAsAdministrator.jpg"><img class="size-full wp-image-829 alignnone" title="RunAsAdministrator" src="http://www.richard-slater.co.uk/wp-content/uploads/2010/10/RunAsAdministrator.jpg" alt="" width="216" height="28" /></a></li>
<li>When prompted click &#8220;Yes&#8221; to allow Command Prompt to start as Administrator.</li>
<li>You will know it has worked because the title bar will start with &#8220;Administrator:&#8221;<br />
<a href="http://www.richard-slater.co.uk/wp-content/uploads/2010/10/AdministratorCommandPrompt.jpg"><img class="size-full wp-image-830 alignnone" title="AdministratorCommandPrompt" src="http://www.richard-slater.co.uk/wp-content/uploads/2010/10/AdministratorCommandPrompt.jpg" alt="" width="433" height="263" /></a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.richard-slater.co.uk/archives/2010/10/07/elevated-command-prompt/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ASP.net 3.5 GridView RowCommand event fired twice</title>
		<link>http://www.richard-slater.co.uk/archives/2010/04/01/asp-net-3-5-gridview-rowcommand-event-fired-twice/</link>
		<comments>http://www.richard-slater.co.uk/archives/2010/04/01/asp-net-3-5-gridview-rowcommand-event-fired-twice/#comments</comments>
		<pubDate>Thu, 01 Apr 2010 15:25:27 +0000</pubDate>
		<dc:creator>Richard Slater</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Sys. Admin.]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.net]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://www.richard-slater.co.uk/?p=763</guid>
		<description><![CDATA[I am writing this up to hopefully save someone else time in the future, this particular problem took up six hours of my day yesterday causing quite a bit of frustration for me, as the developer, and the users of the application. If you are searching for the solution scroll down to the bottom of [...]]]></description>
			<content:encoded><![CDATA[<p>I am writing this up to hopefully save someone else time in the future, this particular problem took up six hours of my day yesterday causing quite a bit of frustration for me, as the developer, and the users of the application.</p>
<p>If you are searching for the solution scroll down to the bottom of the page where I will outline the solution I used to resolve the problem. It is also worth pointing out that this does appear to be fixed in .NET 4. Certainly I was able to consistently reproduce the problem with VS2008/.NET 3.5 on multiple different computers. However after converting the project to VS2010/.NET 5 I haven&#8217;t seen the issue.</p>
<h1>Explanation of the problem</h1>
<p>I wrote and maintain an application that publishes a list of courses and allows users to book onto these courses, what I have listed below is a simplified version of this application.</p>
<p>The administration console contains two lists:</p>
<ul>
<li><strong>Published Courses</strong> &#8211; courses visible to all employees.</li>
<li><strong>Unpublished Courses </strong>- courses waiting to be published, only visible from the administration console.</li>
</ul>
<p>Courses can be freely published (i.e. moved from Unpublished to Published) by clicking green tick. Courses that have not had any bookings made can be unpublished by clicking the red cross.</p>
<p>The cross and the tick are implemented as <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.aspx">GridView</a> <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.buttonfield.aspx">ButtonFields</a>:</p>
<pre>
</pre>
<pre><code>&lt;asp:ButtonField ButtonType="Image" CommandName="UnpublishCourse"
</code><code>    ImageUrl="~/images/unpublish.png" InsertVisible="False" Text="Unpublish" /&gt;
</code></pre>
<p><a href="http://www.richard-slater.co.uk/wp-content/uploads/2010/04/CourseBookings1.png"><img class="aligncenter size-medium wp-image-765" title="CourseBookings" src="http://www.richard-slater.co.uk/wp-content/uploads/2010/04/CourseBookings1-300x114.png" alt="" width="300" height="114" /></a></p>
<p>This application has been running for six months, the issue had not been observed up until yesterday. The user explained to me that when they were publishing courses they were always published in pairs, equally when unpublishing courses it was being done in pairs, concealingly unpublishing a course with bookings.</p>
<h1>Investigating the problem</h1>
<p>Initially I tried to reproduce this on my local machine, backed up and subsequently restored the database locally made sure I was running the same revision as the server and fired it up. Couldn&#8217;t reproduce the problem, no matter how fast I clicked it wouldn&#8217;t happen. Tried various permutations of code and database but could only reproduce on the server.</p>
<p>Refreshed the binaries on the server with the HEAD from subversion, problem was still happening most of the time. I confirmed that it wasn&#8217;t an issue with the stored procedures by running them manually through LinqPad.</p>
<p>I started putting debug statements at the entry points to the critical parts of the code, this yielded an interesting output on my development machine, each time the cross or the tick was clicked UnpublishedGridView_RowCommand was fired twice. This gave me something to search for, seems I am not the only one to have this problem, <a href="https://connect.microsoft.com/VisualStudio/feedback/details/102115/gridview-rowcommand-event-firing-twice">Microsoft tried to reproduce it in 2006</a> but couldn&#8217;t.</p>
<h1>Solving the problem</h1>
<p>As it turns out there are several ways of fixing the problem, several people have used timers to <a href="http://www.labbookpages.co.uk/electronics/debounce.html">&#8220;debounce&#8221;</a> the RowCommand event, assuming that the event is always going to be fired twice a session variable can be used to filter out the second event.</p>
<p>Because the event is only fired twice when ButtonType=&#8221;Image&#8221; not when ButtonType=&#8221;Link&#8221; you can set the text property to the HTML to render your image. This resulted in the code above becomming:</p>
<pre>
</pre>
<pre><code>&lt;asp:ButtonField ButtonType="Link" CommandName="UnpublishCourse"
</code><code>    InsertVisible="False" Text="&lt;img src=images/unpublish.png /&gt;" /&gt;
</code></pre>
<p>This proved to be the simplest possible solution, Visual Studio 2008 throws a warning about ASP.net validation, but I can live with that as long as the application works. In addition to the simplicity of the solution it also continues to work in ASP.net 4 (which doesn&#8217;t exhibit the double event behaviour).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.richard-slater.co.uk/archives/2010/04/01/asp-net-3-5-gridview-rowcommand-event-fired-twice/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>OneNote vs Evernote</title>
		<link>http://www.richard-slater.co.uk/archives/2010/02/27/onenote-vs-evernote/</link>
		<comments>http://www.richard-slater.co.uk/archives/2010/02/27/onenote-vs-evernote/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 20:11:33 +0000</pubDate>
		<dc:creator>Richard Slater</dc:creator>
				<category><![CDATA[Diary]]></category>
		<category><![CDATA[Misc.]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Sys. Admin.]]></category>
		<category><![CDATA[Evernote]]></category>
		<category><![CDATA[Onenote]]></category>

		<guid isPermaLink="false">http://www.richard-slater.co.uk/?p=734</guid>
		<description><![CDATA[Somewhere in the middle of 2007 I was encouraged to use OneNote to clear my desk and move to a &#8220;paperless&#8221; system, initially this was a little painful as it seemed a gargantuan task to scan in all of the bits of paper on and around my desk that appeared to contain useful information. As [...]]]></description>
			<content:encoded><![CDATA[<p>Somewhere in the middle of 2007 I was encouraged to use <a class='wikipedia' href='http://en.wikipedia.org/wiki/OneNote' title='Wikipedia article on OneNote'>OneNote</a> to clear my desk and move to a &#8220;paperless&#8221; system, initially this was a little painful as it seemed a gargantuan task to scan in all of the bits of paper on and around my desk that appeared to contain useful information.</p>
<p>As it turned out I realised that if a bit of paper was covered by another (or in fact covered by anything) it wasn&#8217;t that important to the execution of my role and could probably be thrown in the bin.</p>
<p>At the time I was not using Microsoft Office at home, opting to use <a class='wikipedia' href='http://en.wikipedia.org/wiki/OpenOffice' title='Wikipedia article on OpenOffice'>OpenOffice</a> for the limited needs I had for productivity software. I did however want a better way of organising my paperwork at home, OneNote 2007 came in at about £70 which isn&#8217;t unreasonable for what you got. Then I discovered <a class='wikipedia' href='http://en.wikipedia.org/wiki/Evernote' title='Wikipedia article on Evernote'>Evernote</a>.</p>
<p>Seemed perfect, I don&#8217;t generate so much paperwork that I would bust the 40mb/month limit on the free account. In the end I decided to adopt Evernote at home and continue to use OneNote at work, it proved quite a handy separation of work and life.</p>
<p>Recently I have run into two problems that are pushing me towards using Evernote for everything, and ditching OneNote entirely:</p>
<ol>
<li>Evernote handles PDFs really well, you drag them in and they are displayed using the Foxit rendering engine. It just works. OneNote on the other hand plain old embeds them into the note, great now how is that different from having them in a folder in My Documents.</li>
<li>Evernote 3.5 has vastly improved the synchronization mechanism meaning that I can safely put something on Evernote on my PC and it will be on my laptop shortly after it is turned on next. Microsoft has tried to get this kind of functionality into OneNote and <a class='wikipedia' href='http://en.wikipedia.org/wiki/SharePoint' title='Wikipedia article on SharePoint'>SharePoint</a> however it just doesn&#8217;t work that well, it is too slow and there seems to be a 10 minute refresh cycle hard coded into the product.</li>
</ol>
<p>I am still not sure that I want to ditch OneNote entirely, the 2010 version has some nice labour saving devices built in such as quick screen clippings and image formatting with the fluid user interface. Nothing in OneNote 2010 screams &#8220;don&#8217;t leave me&#8221; though.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.richard-slater.co.uk/archives/2010/02/27/onenote-vs-evernote/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Login failed for user &#8221;</title>
		<link>http://www.richard-slater.co.uk/archives/2010/01/25/login-failed-for-user/</link>
		<comments>http://www.richard-slater.co.uk/archives/2010/01/25/login-failed-for-user/#comments</comments>
		<pubDate>Mon, 25 Jan 2010 13:51:41 +0000</pubDate>
		<dc:creator>Richard Slater</dc:creator>
				<category><![CDATA[Sys. Admin.]]></category>
		<category><![CDATA[Things You Find]]></category>

		<guid isPermaLink="false">http://www.richard-slater.co.uk/?p=724</guid>
		<description><![CDATA[There is an excellent post on the SQL Protocols blog about diagnosing the “Login failed for user &#8221;. The user is not associated with a trusted SQL Server connection.” message displayed by SQL Management Studio and other applications which use the same API; Notice the blank username &#8221;. I believe there is one possibility missing [...]]]></description>
			<content:encoded><![CDATA[<p>There is an <a href="http://blogs.msdn.com/sql_protocols/archive/2008/05/03/understanding-the-error-message-login-failed-for-user-the-user-is-not-associated-with-a-trusted-sql-server-connection.aspx">excellent post</a> on the SQL Protocols blog about diagnosing the <em>“Login failed for user &#8221;. The user is not associated with a trusted SQL Server connection.”</em> message displayed by SQL Management Studio and other applications which use the same API; Notice the blank username &#8221;.</p>
<p>I believe there is one possibility missing from the above post: that is the Group Policy setting &#8220;Deny access to this computer from the network&#8221;. Which can be found in both Domain Group Policy and Local Security Policy in the following path:</p>
<p><em>Computer Configuration » Windows Settings » Security Settings » Local Policies » User Rights Assignment.</em></p>
<p>I have been using this policy more and more to lockdown access to site systems in accordance with our security and access policy. It pays to be cautious when applying User Rights Assignment policies to a machine, as in Windows 2003/XP they are not very granular.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.richard-slater.co.uk/archives/2010/01/25/login-failed-for-user/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Card Reader on Acer Aspire 5100 Series Under Windows 7</title>
		<link>http://www.richard-slater.co.uk/archives/2009/10/26/card-reader-on-acer-aspire-5100-serie-under-windows-7/</link>
		<comments>http://www.richard-slater.co.uk/archives/2009/10/26/card-reader-on-acer-aspire-5100-serie-under-windows-7/#comments</comments>
		<pubDate>Mon, 26 Oct 2009 20:24:56 +0000</pubDate>
		<dc:creator>Richard Slater</dc:creator>
				<category><![CDATA[Sys. Admin.]]></category>
		<category><![CDATA[Driver]]></category>
		<category><![CDATA[Laptop]]></category>

		<guid isPermaLink="false">http://www.richard-slater.co.uk/?p=693</guid>
		<description><![CDATA[Update (15/11/2010): the drivers listed in this post are out of date and may cause a BSOD, several alternatives are listed in the comments; however Microsoft appear to have approved 64-bit drivers on Windows Update. I am typing this on my Acer Aspire 5102WLMi which is one of the popular (if flawed) Acer Aspire 5100 [...]]]></description>
			<content:encoded><![CDATA[<p><span style="color: #ff0000;"><strong>Update (15/11/2010): the drivers listed in this post are out of date and may cause a BSOD, several alternatives are listed in the comments; however Microsoft appear to have approved 64-bit drivers on Windows Update.</strong></span></p>
<p>I am typing this on my Acer Aspire 5102WLMi which is one of the popular (if flawed) Acer Aspire 5100 series; I rescued this one from the Balconi Test by putting a bit of rubber (it was a cut down rubber foot) on top of the <a class='wikipedia' href='http://en.wikipedia.org/wiki/Southbridge_%28computing%29' title='Wikipedia article on Southbridge_(computing)'>South Bridge</a> chip set, that however is not the story I am telling today.</p>
<p>I never bothered to install the Card Reader driver on this laptop while I was running the Windows 7 Beta, mainly because I am lazy, but also I didn&#8217;t have a need for it so it never came up. With the release of Windows 7 I wanted to get the system perfect, seeing as hopefully it will last a good year in it&#8217;s present state, and I wanted to be able to re-arrange the SD card from my Acer PDA.</p>
<p>Windows 7 x64 was unable to identify a driver for this particular card reader, this left me with three unknown devices in Device Manager:</p>
<p><img class="alignnone size-full wp-image-696" title="Missing Drivers Acer 5100" src="http://www.richard-slater.co.uk/wp-content/uploads/2009/10/MissingDriversAcer5100.png" alt="Missing Drivers Acer 5100" width="215" height="94" /></p>
<p>The Acer website was a bust, as far as Acer are concerned this laptop won&#8217;t even run Vista x64, so I had to dig deeper. From past experience of looking for drivers without using Windows Update I knew that I could probably identify the manufacturer from the Hardware and Device ID&#8217;s available through Device Manager. If you want to follow along here are the steps:</p>
<ol>
<li>Open up Device Manager (Right Click &#8220;Computer&#8221;, Choose &#8220;Manage&#8221;, Select &#8220;Device Manager&#8221;)</li>
<li>Identify your unknown devices (They will look similar to the image above, although the text will differ)</li>
<li>Right click one of them and select &#8220;Properties&#8221;</li>
<li>Switch to the &#8220;Details&#8221; tab</li>
<li>Change the property drop down box to read &#8220;Hardware Ids&#8221;</li>
</ol>
<p>What that will give you is one or more strings looking something like this</p>
<pre>PCI\VEN_<strong>1524</strong>&amp;DEV_<strong>0530</strong>&amp;SUBSYS_009F1025&amp;REV_01</pre>
<p>I have marked the two important parts in bold, the four digits after &#8220;VEN_&#8221; tell you the <a class='wikipedia' href='http://en.wikipedia.org/wiki/Conventional_PCI' title='Wikipedia article on Conventional_PCI'>PCI</a> Vendor number, the four digits after &#8220;DEV_&#8221; tells you device number these two numbers should uniquely identify the driver.</p>
<p>There are several sites that allow you to lookup these numbers, I tend to use the publicly available PCI Vendor and Device Lists at <a href="http://www.pcidatabase.com/">PCIDatabase.com</a>. Which has always given me good results with minimum fuss and adverts.</p>
<p>Armed with the above I identified the manufacturer of the Card Reader was ENE Technologies, sometimes this is all you need to find the driver. You can Google/Bing the name and click the download or support links and get the latest drivers. This isn&#8217;t always the way, as some <a class='wikipedia' href='http://en.wikipedia.org/wiki/Original_equipment_manufacturer' title='Wikipedia article on Original_equipment_manufacturer'>OEMs</a> don&#8217;t offer drivers leaving that down to the system integrator to offer that service.</p>
<p>So some time with Bing, I found some drivers for various ENE Devices, however the drivers available from <a href="http://www.versiontracker.com/dyn/moreinfo/win/115639">VersionTracker</a> seemed promising. After downloading and unzipping the contents of the file to a folder on my Desktop, I was able to point Device Manager at these files for each of the unknown devices I was left with three working devices and a fully operational Card Reader.</p>
<p><img class="alignnone size-full wp-image-695" title="ENECardReaderDriversAcer5100" src="http://www.richard-slater.co.uk/wp-content/uploads/2009/10/ENECardReaderDriversAcer5100.png" alt="ENECardReaderDriversAcer5100" width="386" height="113" /></p>
<p>Hope this helps some other people with similar laptops or Card Readers, post in the comments with your experiences, please include the manufacturer and model of the laptop/netbook you have succeeded with and hopefully you will help someone else with the same devices.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.richard-slater.co.uk/archives/2009/10/26/card-reader-on-acer-aspire-5100-serie-under-windows-7/feed/</wfw:commentRss>
		<slash:comments>43</slash:comments>
		</item>
		<item>
		<title>Change your MTU under Vista or Windows 7</title>
		<link>http://www.richard-slater.co.uk/archives/2009/10/23/change-your-mtu-under-vista-or-windows-7/</link>
		<comments>http://www.richard-slater.co.uk/archives/2009/10/23/change-your-mtu-under-vista-or-windows-7/#comments</comments>
		<pubDate>Fri, 23 Oct 2009 20:11:31 +0000</pubDate>
		<dc:creator>Richard Slater</dc:creator>
				<category><![CDATA[Sys. Admin.]]></category>
		<category><![CDATA[MTU]]></category>
		<category><![CDATA[Netsh]]></category>
		<category><![CDATA[TCP/IP]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Windows 7]]></category>
		<category><![CDATA[Windows Vista]]></category>

		<guid isPermaLink="false">http://www.richard-slater.co.uk/?p=683</guid>
		<description><![CDATA[This information is available in many many other places, however I am putting it on here because I know it will be here for me to refer to. Also it is handy, as I know I can access my web-site even if the MTU is misconfigured. For some reason that has escaped me Path MTU [...]]]></description>
			<content:encoded><![CDATA[<p><em>This information is available in many many other places, however I am putting it on here because I know it will be here for me to refer to. Also it is handy, as I know I can access my web-site even if the <a class='wikipedia' href='http://en.wikipedia.org/wiki/Maximum_transmission_unit' title='Wikipedia article on Maximum_transmission_unit'>MTU</a> is misconfigured.</em></p>
<p>For some reason that has escaped me <a class='wikipedia' href='http://en.wikipedia.org/wiki/Path_MTU_discovery' title='Wikipedia article on Path_MTU_discovery'>Path MTU Discovery</a> in Windows just doesn&#8217;t seem to figure out the MTU for a given path (something to do with routers being poorly configured to not respond to <a class='wikipedia' href='http://en.wikipedia.org/wiki/Internet_Control_Message_Protocol' title='Wikipedia article on Internet_Control_Message_Protocol'>ICMP</a> requests). So Windows uses the default. For the most part this doesn&#8217;t affect anyone, however if it dos affect you, it really annoys you. Failure of PMTUD will result in some websites not loading correctly, having trouble connecting to normally reliable online services and general Internet weirdness.</p>
<p>The resolution is to set your default MTU to one lower than the <a class='wikipedia' href='http://en.wikipedia.org/wiki/Ethernet' title='Wikipedia article on Ethernet'>Ethernet</a> default of 1500. Here is how:</p>
<p><strong>Step 1: Find your MTU</strong><br />
From an <a href="http://www.richard-slater.co.uk/archives/2010/10/07/elevated-command-prompt/">elevated CMD Shell</a> enter the following command:</p>

<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;">netsh interface ipv4 show subinterfaces</pre></div></div>

<p>You should get something like this</p>
<pre>MTU         MediaSenseState  Bytes In    Bytes Out  Interface
----------  ---------------  ---------   ---------  -------------
4294967295  1                0           13487914   Loopback Pseudo-Interface 1
1500        1                3734493902  282497358  Local Area Connection</pre>
<p>If you are using Ethernet cable you will be looking for &#8220;Local Area Connection&#8221; or &#8220;Local Area Connection 2&#8243; (if you happened to plug into the second network port). If you are using Wireless you will be looking for &#8220;Wireless Network Connection&#8221;. The MTU is in the first column.</p>
<p><strong>Step 2: Find out what it should be</strong></p>
<p>In the CMD shell type:</p>

<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;">ping www.cantreachthissite.com -f -l 1472</pre></div></div>

<p>The host name should be a site you <span style="text-decoration: underline;"><strong>can not</strong></span> reach, -f marks the packet as one that should not be fragmented the -l 1472 sets the size of the packet (1472 = Ethernet Default MTU &#8211; Packet Header, where the Ethernet Default MTU is 1500 and the Packet Header is 28 bytes)</p>
<p>If the packet can&#8217;t be sent because it would need to be fragmented you will get something similar to this:</p>
<pre>Packet needs to be fragmented but DF set.</pre>
<p>Keep trying lower packet sizes by 10 (i.e. -l 1460, 1450, 1440, etc.) until you get a successful ping request. Raise your packet sizes by one until you get a &#8220;Packet needs to be fragmented but DF set.&#8221;. The last successful value plus 28 will be your MTU value.</p>
<p>In my case a packet size of 1430 succeeds but 1431 fails, so 1430 + 28 = 1458.</p>
<p><strong>Step 3: Set your MTU</strong></p>
<p>Now you have identified the interface you need to change and the ideal MTU for you, now it is time to make the change. Again from an elevated CMD Shell type the following replacing my MTU of 1458 with your own value:</p>

<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;">netsh interface ipv4 <span style="color: #b1b100; font-weight: bold;">set</span> subinterface &quot;Local Area Connection&quot; mtu=1458 store=persistent</pre></div></div>

<p>Or if you are using a Wireless connection:</p>

<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;">netsh interface ipv4 <span style="color: #b1b100; font-weight: bold;">set</span> subinterface &quot;Wireless Network Connection&quot; mtu=1458 store=persistent</pre></div></div>

<p>If all has gone well you should have a perfectly working internet connection.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.richard-slater.co.uk/archives/2009/10/23/change-your-mtu-under-vista-or-windows-7/feed/</wfw:commentRss>
		<slash:comments>87</slash:comments>
		</item>
	</channel>
</rss>

