<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.3.1" -->
<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/"
	>

<channel>
	<title>Exo-Brain Software Blog</title>
	<link>http://blog.exo-brain.com</link>
	<description></description>
	<pubDate>Thu, 21 Feb 2008 00:38:08 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.3.1</generator>
	<language>en</language>
			<item>
		<title>How to Generate Test Data in Bulk</title>
		<link>http://blog.exo-brain.com/how-to-generate-test-data-in-bulk/2008-02-21/</link>
		<comments>http://blog.exo-brain.com/how-to-generate-test-data-in-bulk/2008-02-21/#comments</comments>
		<pubDate>Thu, 21 Feb 2008 00:38:08 +0000</pubDate>
		<dc:creator>Forrest</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[SQL]]></category>

		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://blog.exo-brain.com/how-to-generate-test-data-in-bulk/2008-02-21/</guid>
		<description><![CDATA[Performance tuning in SQL Server is unendingly complex.  At the basic end of the scale are indexes, query plans, disc-based I/O distribution, and the like;  more complex issue demand a lot more investigation and care.  Because the query optimizer&#8217;s job is most heavily centered in disc access - unlike the CLR optimizer, [...]]]></description>
			<content:encoded><![CDATA[<p>Performance tuning in SQL Server is unendingly complex.  At the basic end of the scale are indexes, query plans, disc-based I/O distribution, and the like;  more complex issue demand a lot more investigation and care.  Because the query optimizer&#8217;s job is most heavily centered in disc access - unlike the CLR optimizer, which is best at putting functions inline, and unwinding loops - performance and scalability code can only be realistically tested against data.  Lots and lots of data.</p>
<p>Remote joins are a situation SQL Server could handle better.  Generally, an entire table is copied from one server to the other, which could potentially flood tempdb, then the join is performed locally.  You can use a <a href="http://technet.microsoft.com/en-us/library/ms175002.aspx" title="Evaluating SQL Server performance" target="_blank">query hint</a> to force which table is sent and which server the join is delegated to.  A better solution will come in a later post, although this is just one situation that requires gigabytes of data to properly test.</p>
<p>By custom, this test data often comes from <a href="http://www.dba-oracle.com/t_garmany_9_sql_cross_join.htm" title="Oracle DBA on cross joins for test data" target="_blank">Cartesian joins</a>.  An example is:</p>
<p><code>Select * From sysObjects, sysComments, sysColumns</code></p>
<p>My test server doesn&#8217;t have enough space to execute this code.  If sysComments is removed and the query is executed in a new, empty database, 20,000 rows will be returned ( using SQL Server 2005, Enterprise Edition ).  The trouble is, the rows look very much alike, can easily be mistaken for one another, and make poor test data.  Let&#8217;s try a better approach. <a href="http://blog.exo-brain.com/how-to-generate-test-data-in-bulk/2008-02-21/#more-13" class="more-link">(more&#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.exo-brain.com/how-to-generate-test-data-in-bulk/2008-02-21/feed/</wfw:commentRss>
		</item>
		<item>
		<title>SQL Server Object Search (Advanced T-SQL)</title>
		<link>http://blog.exo-brain.com/sql-server-object-search-advanced-t-sql/2008-01-30/</link>
		<comments>http://blog.exo-brain.com/sql-server-object-search-advanced-t-sql/2008-01-30/#comments</comments>
		<pubDate>Wed, 30 Jan 2008 05:36:47 +0000</pubDate>
		<dc:creator>Forrest</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[SQL]]></category>

		<category><![CDATA[Information Schema]]></category>

		<category><![CDATA[Search]]></category>

		<category><![CDATA[T-SQL]]></category>

		<guid isPermaLink="false">http://blog.exo-brain.com/sql-server-object-search-advanced-t-sql/2008-01-30/</guid>
		<description><![CDATA[Anybody who&#8217;s ever had to work with a SQL Server object without being told which database it lives in, or worked in a huge schema - like Great Plains or SAP - should find this post interesting.  There are several ways to search for a database object by its name or type;  we&#8217;ll [...]]]></description>
			<content:encoded><![CDATA[<p>Anybody who&#8217;s ever had to work with a SQL Server object without being told which database it lives in, or worked in a huge schema - like Great Plains or SAP - should find this post interesting.  There are several ways to search for a database object by its name or type;  we&#8217;ll examine a few options, look into the issues involved, and present code to accomplish our search.</p>
<h2>The Code</h2>
<p><code style="white-space: pre; line-height: 1em"><span style="color: blue">Set NoCount On<br />
Declare</span> @dbName <span style="color: blue">varChar</span>(200), @ins <span style="color: blue">varChar</span>(1000)<span style="color: green">&#8211;Internal use only</span><br />
<span style="color: blue">Declare</span><br />
<span style="margin-left: 10px">@searchName <span style="color: blue">varChar</span>(200),</span><br />
<span style="margin-left: 10px">@objType <span style="color: blue">varChar</span>(2),</span><br />
<span style="margin-left: 10px">@objTypeList <span style="color: blue">varChar</span>(300),</span><br />
<span style="margin-left: 10px">@owner <span style="color: blue">varChar</span>(200),</span><br />
<span style="margin-left: 10px">@excludeName <span style="color: blue">varChar</span>(100),</span><br />
<span style="margin-left: 10px">@ignoreDatabases <span style="color: blue">varChar</span>(1000),</span><br />
<span style="margin-left: 10px">@sort <span style="color: blue">varChar</span>(1000)</span><br />
<span style="color: blue">Set</span> @searchName = <span style="color: red">&#8216;Log&#8217;</span><br />
/*<span style="color: green">Set @objTypeList = &#8216;U, P, V, FN, TR&#8217;<br />
Set @objType = &#8216;P&#8217;<br />
Set @owner = &#8216;dbo&#8217;<br />
Set @excludeName = &#8216;Backup-Log&#8217;</span>*/<br />
<span style="color: blue">Set</span> @searchName = <span style="color: pink">IsNull</span>(@searchName, <span style="color: red">&#8221;</span>)<br />
<span style="color: blue">Set</span> @sort = <span style="color: pink">IsNull</span>(@sort, <span style="color: red">&#8216;DatabaseName, SchemaOwner, SqlObjectType&#8217;</span>)<br />
<span style="color: blue">Set</span> @ignoreDatabases = <span style="color: pink">IsNull</span>(@ignoreDatabases, <span style="color: red">&#8216;model, msdb, tempDB, master, ReportServerTempDB, ReportServer&#8217;</span>)<br />
<span style="color: blue">Create Table</span> #sqlSearchResults ( DatabaseName <span style="color: blue">varChar</span>(200), SchemaOwner <span style="color: blue">varChar</span>(100), ObjectName <span style="color: blue">varChar</span>(200), SqlObjectType <span style="color: blue">varChar</span>(2) )<br />
<span style="color: blue">Declare</span> c <span style="color: blue">Cursor</span> Forward_Only <span style="color: blue">For</span><br />
<span style="color: blue">Select name From master</span>.dbo.sysDatabases<br />
<span style="color: blue">For Read</span> Only<br />
<span style="color: blue">Open</span> c<br />
<span style="color: blue">Fetch</span> Next <span style="color: blue">From</span> c <span style="color: blue">Into</span> @dbName<br />
<span style="color: blue">While</span> <span style="color: pink">@@Fetch_Status</span> = 0 <span style="color: blue">Begin</span><br />
<span style="color: blue">If</span> <span style="color: pink">PatIndex</span>(&#8217;%&#8217; + @dbName + &#8216;%&#8217;, @ignoreDatabases) &lt;= 0 <span style="color: blue">Begin</span><br />
<span style="color: blue">Set</span> @ins = <span style="color: red">&#8216;Insert Into #sqlSearchResults Select &#8221;&#8217;</span> + @dbName + <span style="color: red">&#8221;&#8217; As DatabaseName, IsNull(U.Name, &#8221;???&#8221;), O.Name, xType From &#8216;</span> + @dbName + <span style="color: red">&#8216;.dbo.sysObjects O Left Join &#8216; + @dbName + &#8216;.dbo.sysUsers U On O.uid = U.uid Where (O.Name Like &#8221;&#8217;</span> + <span style="color: red">&#8216;%&#8217;</span> + @searchName + <span style="color: red">&#8216;%&#8221;)&#8217;</span><br />
<span style="color: blue">If</span> @objType Is Not Null Set @ins = @ins + <span style="color: red">&#8216; And (xType = &#8216; + &#8221;&#8221; + @objType + &#8221;&#8217;)&#8217;</span><br />
<span style="color: blue">If</span> @owner Is Not Null Set @ins = @ins + <span style="color: red">&#8216; And (U.Name = &#8216; + &#8221;&#8221; + @owner + &#8221;&#8217;)&#8217;</span><br />
<span style="color: blue">If</span> @objTypeList Is Not Null Set @ins = @ins + <span style="color: red">&#8216; And (&#8221;&#8217;</span> + @objTypeList + <span style="color: red">&#8221;&#8217; Like &#8221;%&#8221;</span> + rTrim(xType) + <span style="color: red">&#8221;%&#8221;)&#8217;</span><br />
<span style="color: blue">If</span> @excludeName Is Not Null Set @ins = @ins + <span style="color: red">&#8216; And (O.Name Not Like &#8216;</span> + <span style="color: red">&#8221;&#8217;%&#8217;</span> + @excludeName + <span style="color: red">&#8216;%&#8221;)&#8217;</span><br />
<span style="color: blue">Exec</span>(@ins)<br />
<span style="color: blue">End</span><br />
<span style="color: green">&#8211;Print @ins</span><br />
<span style="color: blue">Fetch</span> Next <span style="color: blue">From</span> c <span style="color: blue">Into</span> @dbName<br />
<span style="color: blue">End<br />
Close</span> c<br />
<span style="color: blue">DeAllocate</span> c<br />
Exec(<span style="color: red">&#8216;Select * From #sqlSearchResults Order By &#8216;</span> + @sort)<br />
<span style="color: blue">Drop Table</span> #sqlSearchResults</code></p>
<h2>Arguments</h2>
<p>There are seven variables you can set to control the search.  All are optional;  passing nothing in will return a list of all objects in all non-system databases. <a href="http://blog.exo-brain.com/sql-server-object-search-advanced-t-sql/2008-01-30/#more-12" class="more-link">(more&#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.exo-brain.com/sql-server-object-search-advanced-t-sql/2008-01-30/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Breaking Out of Frames (Except Google Images)</title>
		<link>http://blog.exo-brain.com/breaking-out-of-frames-except-google-images/2007-10-16/</link>
		<comments>http://blog.exo-brain.com/breaking-out-of-frames-except-google-images/2007-10-16/#comments</comments>
		<pubDate>Tue, 16 Oct 2007 18:07:32 +0000</pubDate>
		<dc:creator>Forrest</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://blog.exo-brain.com/breaking-out-of-frames-except-google-images/2007-10-16/</guid>
		<description><![CDATA[Most of us have an interest in protecting our content from digital thieves, which, sadly, the internet is full of.  There are any number of ways a person can steal content from your site;  in this article we&#8217;ll look into frames.  They generally fell out of favor shortly after being introduced, but [...]]]></description>
			<content:encoded><![CDATA[<p>Most of us have an interest in protecting our content from digital thieves, which, sadly, the internet is full of.  There are any number of ways a person can steal content from your site;  in this article we&#8217;ll look into frames.  They generally fell out of favor shortly after being introduced, but while they&#8217;re used only in a minority of sites, they <em>are</em> still being used.</p>
<p><a href="http://images.google.com/imghp?tab=wi" title="Google Image Search - Frameset Example" target="_blank">Google Images</a> is an example, and an edge case.  Clicking an image from the search results takes you to a frameset, with Google&#8217;s branding along the top of the browser window, and the page the image was found on below.  This is permissible use, however;  Google Images sends my <a href="http://forrestcroce.com/Galleries/All.html" title="Photo Galleries" target="_blank">photography site</a> about 8,500 visitors per month.</p>
<p>There are three main ways to steal and republish visual content, be it an image, video, or other media: <a href="http://blog.exo-brain.com/breaking-out-of-frames-except-google-images/2007-10-16/#more-9" class="more-link">(more&#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.exo-brain.com/breaking-out-of-frames-except-google-images/2007-10-16/feed/</wfw:commentRss>
		</item>
		<item>
		<title>URL Rewriting in ASP</title>
		<link>http://blog.exo-brain.com/url-rewriting-in-asp/2007-10-07/</link>
		<comments>http://blog.exo-brain.com/url-rewriting-in-asp/2007-10-07/#comments</comments>
		<pubDate>Sun, 07 Oct 2007 05:05:47 +0000</pubDate>
		<dc:creator>Forrest</dc:creator>
		
		<category><![CDATA[.net]]></category>

		<category><![CDATA[Code]]></category>

		<category><![CDATA[Software Design]]></category>

		<guid isPermaLink="false">http://blog.exo-brain.com/url-rewriting-in-asp/2007-10-07/</guid>
		<description><![CDATA[&#8220;Rewriting&#8221; means intercepting a request from the web, and responding with the document behind a different URL.  If this sounds like a redirect, it should;  the main difference is that we&#8217;ll be doing this internally, without the client&#8217;s knowledge.  ( The &#8220;client&#8221; is Internet Explorer, FireFox, Safari, or GoogleBot. )  In [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;Rewriting&#8221; means intercepting a request from the web, and responding with the document behind a different URL.  If this sounds like a redirect, it should;  the main difference is that we&#8217;ll be doing this internally, without the client&#8217;s knowledge.  ( The &#8220;client&#8221; is <a href="http://www.microsoft.com/windows/products/winfamily/ie/default.mspx" title="MSIE - The browser of the devil" target="_blank">Internet Explorer</a>, <a href="http://www.mozilla.com/en-US/firefox/" title="Mozilla Fire Fox" target="_blank">FireFox</a>, <a href="http://www.apple.com/safari/" title="Apple / Mac Safari browser" target="_blank">Safari</a>, or <a href="http://www.google.com/support/webmasters/bin/topic.py?topic=8843" title="Google's Q&amp;A on their bot" target="_blank">GoogleBot</a>. )  In other words, <u>www.example.com/page.aspx?search=software</u> becomes exposed to the outside world as <u>www.example.com/page/search/software</u>;  when somebody asks for the latter, the request is internally sent to the former.</p>
<p>You might do this after restructuring a web site, to prevent links to moved pages from turning into dead ends.  Or, you might do it to improve your standing with search engines, the way most WordPress blogs use a post&#8217;s date and title, rather than it&#8217;s ID in the database, to create &#8220;permalinks.&#8221;  On <a href="http://www.apache.org/" title="Apache" target="_blank">Apache</a> servers, this is accomplished with <a href="http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html" title="Apache Server Documentation on the voodoo that is mod rewrite" target="_blank">mod_rewrite</a> in the <a href="http://httpd.apache.org/docs/1.3/howto/htaccess.html" title="Documentation for the .htaccess file" target="_blank">.htaccess</a> file, which isn&#8217;t available to IIS users.</p>
<p>Instead, developers running Microsoft&#8217;s web server, <em>Internet Information Services</em>, or IIS, have three options for rewriting.  Let&#8217;s examine these, in reverse order by difficulty and cleverness. <a href="http://blog.exo-brain.com/url-rewriting-in-asp/2007-10-07/#more-8" class="more-link">(more&#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.exo-brain.com/url-rewriting-in-asp/2007-10-07/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Requesting Web URL Status From .net Code</title>
		<link>http://blog.exo-brain.com/requesting-web-url-status-from-net-code/2007-09-22/</link>
		<comments>http://blog.exo-brain.com/requesting-web-url-status-from-net-code/2007-09-22/#comments</comments>
		<pubDate>Sat, 22 Sep 2007 04:45:01 +0000</pubDate>
		<dc:creator>Forrest</dc:creator>
		
		<category><![CDATA[.net]]></category>

		<category><![CDATA[Code]]></category>

		<category><![CDATA[Software Design]]></category>

		<guid isPermaLink="false">http://blog.exo-brain.com/requesting-web-url-status-from-net-code/2007-09-22/</guid>
		<description><![CDATA[There are any number of reasons to want to programmatically interact with resources on the web.  Some of the more well known are browsers, like Internet Explorer, FireFox, and Safari; search engine spiders like GoogleBot; and RSS readers.  Less famous are automated testing tools checking for 404 (Page not Found) and other errors. [...]]]></description>
			<content:encoded><![CDATA[<p>There are any number of reasons to want to programmatically interact with resources on the web.  Some of the more well known are browsers, like Internet Explorer, FireFox, and Safari; search engine spiders like GoogleBot; and RSS readers.  Less famous are automated testing tools checking for 404 (Page not Found) and other errors.  As people who maintain sites delve into IIS, cPanel, .htaccess, or custom authentication code, it becomes important to verify that pages are returning an HTTP status code of 200 (OK) when you expect them to, or the right type of redirect (temporary vs permanent).  Testing software aims to identify unknown problems in a larger site that becomes difficult to manage by hand.</p>
<p>While some of these tools are worth the price, they can easily become overkill.  Especially considering how easy it is to gather this information yourself.  Using the built-in functionality of the Microsoft .net Framework, we can gather a wealth of information about any reachable URL.  From this point, testing an entire site involves little more than writing a loop.  The code provided below doesn&#8217;t check whether the host machine is connected to the internet;  if not a suitable error will be returned to the caller.  For an example of how to test a machine&#8217;s connectivity, see this <a href="http://www.aspemporium.com/howto.aspx?hid=27" title="How to tell whether the computer running your code can reach the internet - InternetGetConnectedState WinInet system call" target="_blank">ASP Emporium</a> article.</p>
<p>The WebStatus object defined below is re-usable, in the sense that once an instance of the class has been created, you can either use the object to cache state info until it falls out of scope, <em>or</em> you can use the object again and again to query new URLs.  This has nothing to do with object oriented programming, but reduces pressure on the managed heap, allowing your application to use less memory and force less <a href="http://msdn.microsoft.com/msdnmag/issues/1100/gci/" title="Microsoft Developer Network article on GC" target="_blank">garbage collections</a>.</p>
<p> <a href="http://blog.exo-brain.com/requesting-web-url-status-from-net-code/2007-09-22/#more-6" class="more-link">(more&#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.exo-brain.com/requesting-web-url-status-from-net-code/2007-09-22/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Displaying Graceful Exception Info</title>
		<link>http://blog.exo-brain.com/displaying-graceful-exception-info/2007-08-06/</link>
		<comments>http://blog.exo-brain.com/displaying-graceful-exception-info/2007-08-06/#comments</comments>
		<pubDate>Mon, 06 Aug 2007 02:22:56 +0000</pubDate>
		<dc:creator>Forrest</dc:creator>
		
		<category><![CDATA[.net]]></category>

		<category><![CDATA[Code]]></category>

		<category><![CDATA[Logging]]></category>

		<category><![CDATA[Software Design]]></category>

		<guid isPermaLink="false">http://blog.exo-brain.com/displaying-graceful-exception-info/2007/08/06/</guid>
		<description><![CDATA[For better or worse, exceptions are a part of life.  Any non-trivial application is going to generate them, at least occasionally, when something exceptional happens.  One shouldn&#8217;t rely on exceptions for control of flow;  return values are much better at this in many ways.  And a person should run tests to [...]]]></description>
			<content:encoded><![CDATA[<p>For better or worse, exceptions are a part of life.  Any non-trivial application is going to generate them, at least occasionally, when something exceptional happens.  One shouldn&#8217;t rely on exceptions for control of flow;  return values are much better at this in many ways.  And a person should run tests to prevent exceptions, when it&#8217;s possible &#8230; make sure a number isn&#8217;t zero before dividing by it.</p>
<p>When an exception, which is really just a modern term for an error, <em>does</em> rear its ugly head, in addition to handling it gracefully, most applications need to <em>do something</em> with it.  This might involve showing a message to the user, logging the fact that a problem happened for later inspection, or any number of things.  A new open-source .net expands your options.</p>
<p><strong>ExpressionFormatter </strong>is a static class, written in C# and targeting the <em>Microsoft.net framework v2</em>, that turns a managed <span style="color: #33ddff; font-weight: bold">Exception</span> object into an html stream.  In an ASP.NET application this lets you send a detailed, easily readable message directrly to the client (<em>after they&#8217;ve been authorized!</em>), but in a middle-tier, server-based application html is a fantastic way to store exception details for later review and drill-down analysis.  In a Windows Forms client, you can log the exception for later use, and when it makes sense to, you can display it to the client using either a <strong>WebBrowser</strong> control or by writing an html file and using <strong>Process.Start</strong> to launch it.</p>
<p> <a href="http://blog.exo-brain.com/displaying-graceful-exception-info/2007-08-06/#more-3" class="more-link">(more&#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.exo-brain.com/displaying-graceful-exception-info/2007-08-06/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
