<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>Programming</title><link>http://blogs.acceleration.net/ryan/category/2.aspx</link><description>Catch-all for any programming rant</description><managingEditor>Ryan</managingEditor><dc:language>en-US</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>Ryan</dc:creator><title>RE: Lisp Library Management</title><link>http://blogs.acceleration.net/ryan/archive/2006/05/26/2955.aspx</link><pubDate>Fri, 26 May 2006 11:37:00 GMT</pubDate><guid>http://blogs.acceleration.net/ryan/archive/2006/05/26/2955.aspx</guid><description>&lt;p&gt;
	      &lt;a href="http://www.metabang.com/unclog/"&gt;Gary King&lt;/a&gt; has been working on getting a good library system for lisp, and recently posted his &lt;a href="http://www.metabang.com/unclog/publisha/notesona.html"&gt;Notes on a Lisp Library Management&lt;/a&gt;.  I was going to email him back, but figured here was as good a place as any to give my comments.  Read that first.
	    &lt;/p&gt;
	    &lt;p&gt;
	      Firstly, I applaud Gary for taking up this mantle.   I'm really still starting using lisp, and the lack of authoritative libraries is a hinderer for people like me.  Getting a comprehensive library management system is going to help folks like me get up to speed with lisp faster.  ASDF is a good start, but I think it needs to be built upon. Secondly, sorry if everything I'm saying here has already been considered.
	    &lt;/p&gt;
	    &lt;p&gt;
	        The problem of getting libraries installed and updated with minimal user effort is a very studied problem with several decent implementations that could be used as starting points.
	    &lt;/p&gt;
	    &lt;p&gt;
	      I think a lot of lessons can be learned by studying perl's &lt;a href="http://cpan.org/"&gt;CPAN&lt;/a&gt;.  CPAN has mirrors that automatically sync, and each user picks a list of mirrors near them.  Then you just ask for the package name, and it will download, make, run tests, then put the code in a proper system or user path such that programs can import the library.  Perhaps a port of CPAN would solve most of these problems.
	    &lt;/p&gt;
	    &lt;p&gt;
	      Another good example could be Debian's apt-get.  I think it's command line interface almost perfect, and since many lisp developers are using debian based sytems, the interface would be very familiar.  As a client of a lisp library management service, here's what I think would be ideal, presented as a mock shell session (with user input in bold):
	      &lt;/p&gt;&lt;pre&gt;
~$ &lt;strong&gt;asdf install clsql&lt;/strong&gt;
Looking up definition for package clsql... package found.
GPG key not present, downloading from https://www.b9.com/kevin.gpg.asc... done.
Downloading clsql from http://files.b9.com/clsql/clsql-3.6.1.tar.gz... done.
Checking signature for clsql-3.6.1.tar.gz... file verified.
Checking dependencies...
  clsql depends upon uninstalled package uffi, install uffi? [ynaq] &lt;strong&gt;y&lt;/strong&gt;
    Looking up definition for package uffi... package found.
    Downloading uffi from http://files.b9.com/uffi/uffi-1.5.13.tar.gz... done.
    Checking signature for uffi-1.5.13.tar.gz... file verified.
    Checking dependencies... done.
    Dependencies met.
    Building uffi... done.
    uffi (1.5.13) installed.
Dependencies met.
Building clsql... done.
clsql (3.6.1) installed.
~$ &lt;strong&gt;asdf upgrade&lt;/strong&gt;
Scanning installed packages.
Checking clsql (3.6.1)... up to date.
Checking uffi (1.5.13)... up to date.
Checking my-unversioned-lib (20060503)... outdated!
  Looking up definition for package my-unversioned-lib... package found.
  Downloading my-unversioned-lib from http://example.org/my-unversioned-lib.tar.gz... done.
  Checking signature for my-unversioned-lib.tar.gz... file verified.
  Checking dependencies... done.
  Dependencies met.
  Building my-unversioned-lib... done.
  my-unversioned-lib (20060526) installed.
Upgrade complete, 3 packages processed.
  1 package upgraded.
  2 packages up to date.
	    &lt;/pre&gt;

	    Anyway, enough pipe-dreaming for me.
	    &lt;img src ="http://blogs.acceleration.net/ryan/aggbug/2955.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>
	      <a href="http://www.metabang.com/unclog/">Gary King</a> has been working on getting a good library system for lisp, and recently posted his <a href="http://www.metabang.com/unclog/publisha/notesona.html">Notes on a Lisp Library Management</a>.  I was going to email him back, but figured here was as good a place as any to give my comments.  Read that first.
	    </p>
	    <p>
	      Firstly, I applaud Gary for taking up this mantle.   I'm really still starting using lisp, and the lack of authoritative libraries is a hinderer for people like me.  Getting a comprehensive library management system is going to help folks like me get up to speed with lisp faster.  ASDF is a good start, but I think it needs to be built upon. Secondly, sorry if everything I'm saying here has already been considered.
	    </p>
	    <p>
	        The problem of getting libraries installed and updated with minimal user effort is a very studied problem with several decent implementations that could be used as starting points.
	    </p>
	    <p>
	      I think a lot of lessons can be learned by studying perl's <a href="http://cpan.org/">CPAN</a>.  CPAN has mirrors that automatically sync, and each user picks a list of mirrors near them.  Then you just ask for the package name, and it will download, make, run tests, then put the code in a proper system or user path such that programs can import the library.  Perhaps a port of CPAN would solve most of these problems.
	    </p>
	    <p>
	      Another good example could be Debian's apt-get.  I think it's command line interface almost perfect, and since many lisp developers are using debian based sytems, the interface would be very familiar.  As a client of a lisp library management service, here's what I think would be ideal, presented as a mock shell session (with user input in bold):
	      </p><pre>
~$ <strong>asdf install clsql</strong>
Looking up definition for package clsql... package found.
GPG key not present, downloading from https://www.b9.com/kevin.gpg.asc... done.
Downloading clsql from http://files.b9.com/clsql/clsql-3.6.1.tar.gz... done.
Checking signature for clsql-3.6.1.tar.gz... file verified.
Checking dependencies...
  clsql depends upon uninstalled package uffi, install uffi? [ynaq] <strong>y</strong>
    Looking up definition for package uffi... package found.
    Downloading uffi from http://files.b9.com/uffi/uffi-1.5.13.tar.gz... done.
    Checking signature for uffi-1.5.13.tar.gz... file verified.
    Checking dependencies... done.
    Dependencies met.
    Building uffi... done.
    uffi (1.5.13) installed.
Dependencies met.
Building clsql... done.
clsql (3.6.1) installed.
~$ <strong>asdf upgrade</strong>
Scanning installed packages.
Checking clsql (3.6.1)... up to date.
Checking uffi (1.5.13)... up to date.
Checking my-unversioned-lib (20060503)... outdated!
  Looking up definition for package my-unversioned-lib... package found.
  Downloading my-unversioned-lib from http://example.org/my-unversioned-lib.tar.gz... done.
  Checking signature for my-unversioned-lib.tar.gz... file verified.
  Checking dependencies... done.
  Dependencies met.
  Building my-unversioned-lib... done.
  my-unversioned-lib (20060526) installed.
Upgrade complete, 3 packages processed.
  1 package upgraded.
  2 packages up to date.
	    </pre>

	    Anyway, enough pipe-dreaming for me.
	    <img src ="http://blogs.acceleration.net/ryan/aggbug/2955.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Ryan</dc:creator><title>NETWORKIO locks on SQL Server 2000</title><link>http://blogs.acceleration.net/ryan/archive/2006/05/12/2870.aspx</link><pubDate>Fri, 12 May 2006 13:52:00 GMT</pubDate><guid>http://blogs.acceleration.net/ryan/archive/2006/05/12/2870.aspx</guid><description>&lt;p&gt;
	      Recently I was doing some perfomance tuning for a client, who kept getting timeouts.  The timeouts were being caused by some locking queries, with a lock type of "NETWORKIO".  This is odd, as everything was running on the same server, so it shouldn't really have much network IO when connecting to 127.0.0.1.
	    &lt;/p&gt;
	    &lt;h3&gt;My solution&lt;/h3&gt;
	    &lt;p&gt;
	      After much frustraction and googling, I saw someone recommend updating statistics using &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tsqlref/ts_sp_ua-uz_14kz.asp"&gt;sp_updatestats&lt;/a&gt; to speed up queries, which might resolve NETWORKIO locks faster.  That made all the difference.  Now the site is zippy as hell.  But why did that work?
	    &lt;/p&gt;
	    &lt;p&gt;
	      After some cursory research, I found that &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tsqlref/ts_sp_ua-uz_14kz.asp"&gt;sp_updatestats&lt;/a&gt; is a convienence function for running &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tsqlref/ts_ua-uz_1mpf.asp"&gt;UPDATE STATISTICS&lt;/a&gt; on every table in the current database.  The statistics they talk about are about the keys in each index on the table.  The stats are then analyzed by the query optimizer to get the best usage of indexes.  If you do a "display estimated execution plan" on a query, the stats are whats used to make those estimates.  Then it made sense.
	    &lt;/p&gt;
	    &lt;p&gt;
	      In an earlier attempt to speed everything up, I had taken a trace of the activity and ran the index tuning wizard on about an hours worth of actual usage.  Applying the recommended indexes sped up the site nicely, but the real benefit wasn't realized because the statistics on the new indices hadn't been calculated, so the query optimizer couldn't do its job very well.  After getting my stats lined up, the optimizer kicked in and everything was very responsive.
	    &lt;/p&gt;
	    &lt;h3&gt;Conclusion&lt;/h3&gt;
	    &lt;p&gt;
	      If you change your indexes about, run &lt;code&gt;EXEC sp_updatestats&lt;/code&gt;.  There is an option on a database maintanence plan to do this, and I believe I'm going to start enabling it.
	    &lt;/p&gt;&lt;img src ="http://blogs.acceleration.net/ryan/aggbug/2870.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>
	      Recently I was doing some perfomance tuning for a client, who kept getting timeouts.  The timeouts were being caused by some locking queries, with a lock type of "NETWORKIO".  This is odd, as everything was running on the same server, so it shouldn't really have much network IO when connecting to 127.0.0.1.
	    </p>
	    <h3>My solution</h3>
	    <p>
	      After much frustraction and googling, I saw someone recommend updating statistics using <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tsqlref/ts_sp_ua-uz_14kz.asp">sp_updatestats</a> to speed up queries, which might resolve NETWORKIO locks faster.  That made all the difference.  Now the site is zippy as hell.  But why did that work?
	    </p>
	    <p>
	      After some cursory research, I found that <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tsqlref/ts_sp_ua-uz_14kz.asp">sp_updatestats</a> is a convienence function for running <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tsqlref/ts_ua-uz_1mpf.asp">UPDATE STATISTICS</a> on every table in the current database.  The statistics they talk about are about the keys in each index on the table.  The stats are then analyzed by the query optimizer to get the best usage of indexes.  If you do a "display estimated execution plan" on a query, the stats are whats used to make those estimates.  Then it made sense.
	    </p>
	    <p>
	      In an earlier attempt to speed everything up, I had taken a trace of the activity and ran the index tuning wizard on about an hours worth of actual usage.  Applying the recommended indexes sped up the site nicely, but the real benefit wasn't realized because the statistics on the new indices hadn't been calculated, so the query optimizer couldn't do its job very well.  After getting my stats lined up, the optimizer kicked in and everything was very responsive.
	    </p>
	    <h3>Conclusion</h3>
	    <p>
	      If you change your indexes about, run <code>EXEC sp_updatestats</code>.  There is an option on a database maintanence plan to do this, and I believe I'm going to start enabling it.
	    </p><img src ="http://blogs.acceleration.net/ryan/aggbug/2870.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Ryan</dc:creator><title>Ball of hate, now with Flash&amp;#153</title><link>http://blogs.acceleration.net/ryan/archive/2006/04/05/2853.aspx</link><pubDate>Wed, 05 Apr 2006 17:28:00 GMT</pubDate><guid>http://blogs.acceleration.net/ryan/archive/2006/04/05/2853.aspx</guid><description>&lt;p&gt;
				  So today I had a client call and ask why their site had errors.  They had a secure certificate, and IE was giving a &lt;a href="http://support.microsoft.com/?kbid=184960"&gt;popup&lt;/a&gt;:
				&lt;/p&gt;&lt;blockquote&gt; "This page contains both secure and non-secure items. Do you want to download the non-secure items?" &lt;/blockquote&gt;
				So, I pull up the page, and check the source, figuring there's some &lt;code&gt;&amp;lt;img src="http://..."&lt;/code&gt; somewhere in there.  A ctrl-f later, I see there are no non-secure images.  The only things not using https are links to other sites, and some crap in the &lt;a href="http://fishbowl.pastiche.org/2003/05/28/the_ghetto_minipattern"&gt;code ghetto&lt;/a&gt; that is the markup needed for a flash movie.  Specifically, I saw:
&lt;div class="code"&gt;
&lt;table class="dp-xml" border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;OBJECT &lt;/span&gt;&lt;span class="attribute"&gt;classid&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="attribute"&gt;codebase&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"http://download.macromedia.com/pub/[blah]"&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="attribute"&gt;WIDTH&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"88"&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="attribute"&gt;HEIGHT&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"31"&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="attribute"&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"PoweredBy_88_31_A"&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="attribute"&gt;ALIGN&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;""&lt;/span&gt;&lt;span&gt; VIEWASTEXT&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;[40 lines of garbage] &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;EMBED &lt;/span&gt;&lt;span class="attribute"&gt;SRC&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"[flash file]"&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="attribute"&gt;swLiveConnect&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;FALSE&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="attribute"&gt;WIDTH&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;228&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="attribute"&gt;HEIGHT&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;287&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="attribute"&gt;QUALITY&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;AUTOLOW&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="attribute"&gt;MENU&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;false&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="attribute"&gt;PLAY&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;true&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="attribute"&gt;BGCOLOR&lt;/span&gt;&lt;span&gt;=#FFFFFF &lt;/span&gt;&lt;span class="attribute"&gt;TYPE&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"application/x-shockwave-flash"&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="attribute"&gt;PLUGINSPAGE&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"http://www.macromedia.com/[blah]"&lt;/span&gt;&lt;span&gt;&amp;gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;EMBED&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
				So, on &lt;a title="Nathan's blog" href="http://blogs.acceleration.net/birdman/"&gt;Nathan&lt;/a&gt;'s suggestion, I tried changing this boilerplate mess to make the &lt;code&gt;pluginspace&lt;/code&gt; and &lt;code&gt;codebase&lt;/code&gt; attributes point to https.  That made IE stop throwing the error.  I'm not sure why it was downloading things from those URLs (as the  error message clearly stated), but now its happy, and my client's clients are no longer scared to use the site.
				
				&lt;p&gt;
				  But the fun doesn't end there.  I took a stress break and ran across a blog entry by &lt;a href="http://www.jasongraphix.com"&gt;Jason&lt;/a&gt; about his &lt;a href="http://www.jasongraphix.com/archive/2006/04/activex_update"&gt;ActiveX update woes&lt;/a&gt;.  Apparently to avoid paying licensing fees, Microsoft is changing how IE loads plugins (including flash), and unless developers (developers, developers, developers!) change how they render Flash, the users will be presented with a "Click here to activate this" dialog instead of just showing the flash.  
&lt;/p&gt;&lt;p&gt;
				  Apparently you have to "activate" a plugin before it will run.  More information can be found here: &lt;a href="http://blog.deconcept.com/2005/12/15/internet-explorer-eolas-changes-and-the-flash-plugin/"&gt;Internet Explorer Eolas changes and the Flash plugin&lt;/a&gt;.  
&lt;/p&gt;&lt;p&gt;
				  Like any good security measure, this can be instantly circumvented from the server (attacker) side.  Apparently if you set it up with javascript, then it doesn't need to be activated.  I guess there's no such thing as malicious javascript.  Microsoft has their workaround: &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/overview/activating_activex.asp "&gt;activating ActiveX controls&lt;/a&gt;, and the author of the helpful article above has a widely used Flash rendering javascript library that works too, called &lt;a href="http://blog.deconcept.com/flashobject/"&gt;FlashObject&lt;/a&gt;.  He's written a few books on flash, and his library looks pretty nice, both hiding the &amp;lt;OBJECT&amp;gt; mess and gracefully degrading to plain HTML if the flash plugin is absent.
				&lt;/p&gt;
				&lt;p&gt;
				  Thanks Microsoft, thanks to your change (and Jason's post) I've discovered some nice open source library to remove a slurry of meaningless markup, but I would really prefer not to have to do your legal work.
				&lt;/p&gt;&lt;img src ="http://blogs.acceleration.net/ryan/aggbug/2853.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>
				  So today I had a client call and ask why their site had errors.  They had a secure certificate, and IE was giving a <a href="http://support.microsoft.com/?kbid=184960">popup</a>:
				</p><blockquote> "This page contains both secure and non-secure items. Do you want to download the non-secure items?" </blockquote>
				So, I pull up the page, and check the source, figuring there's some <code>&lt;img src="http://..."</code> somewhere in there.  A ctrl-f later, I see there are no non-secure images.  The only things not using https are links to other sites, and some crap in the <a href="http://fishbowl.pastiche.org/2003/05/28/the_ghetto_minipattern">code ghetto</a> that is the markup needed for a flash movie.  Specifically, I saw:
<div class="code">
<table class="dp-xml" border="0" cellpadding="0" cellspacing="0"><tbody><tr></tr><tr><td class="line"><span></span><span class="tag">&lt;</span><span>OBJECT </span><span class="attribute">classid</span><span>=</span><span class="attribute-value">"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"</span><span>  </span></td></tr><tr><td class="line"><span class="attribute">codebase</span><span>=</span><span class="attribute-value">"http://download.macromedia.com/pub/[blah]"</span><span>  </span></td></tr><tr><td class="line"><span class="attribute">WIDTH</span><span>=</span><span class="attribute-value">"88"</span><span> </span><span class="attribute">HEIGHT</span><span>=</span><span class="attribute-value">"31"</span><span> </span><span class="attribute">id</span><span>=</span><span class="attribute-value">"PoweredBy_88_31_A"</span><span>  </span></td></tr><tr><td class="line"><span class="attribute">ALIGN</span><span>=</span><span class="attribute-value">""</span><span> VIEWASTEXT</span><span class="tag">&gt;</span><span>  </span></td></tr><tr><td class="line"> </td></tr><tr><td class="line">[40 lines of garbage] </td></tr><tr><td class="line"> </td></tr><tr><td class="line"><span class="tag">&lt;</span><span>EMBED </span><span class="attribute">SRC</span><span>=</span><span class="attribute-value">"[flash file]"</span><span> </span></td></tr><tr><td class="line"><span class="attribute">swLiveConnect</span><span>=</span><span class="attribute-value">FALSE</span><span> </span><span class="attribute">WIDTH</span><span>=</span><span class="attribute-value">228</span><span> </span><span class="attribute">HEIGHT</span><span>=</span><span class="attribute-value">287</span><span>  </span></td></tr><tr><td class="line"><span class="attribute">QUALITY</span><span>=</span><span class="attribute-value">AUTOLOW</span><span> </span><span class="attribute">MENU</span><span>=</span><span class="attribute-value">false</span><span> </span><span class="attribute">PLAY</span><span>=</span><span class="attribute-value">true</span><span> </span></td></tr><tr><td class="line"><span class="attribute">BGCOLOR</span><span>=#FFFFFF </span><span class="attribute">TYPE</span><span>=</span><span class="attribute-value">"application/x-shockwave-flash"</span><span> </span></td></tr><tr><td class="line"><span class="attribute">PLUGINSPAGE</span><span>=</span><span class="attribute-value">"http://www.macromedia.com/[blah]"</span><span>&gt; </span></td></tr><tr><td class="line"><span class="tag">&lt;/</span><span>EMBED</span><span class="tag">&gt;</span><span> </span></td></tr></tbody></table>
</div>
				So, on <a title="Nathan's blog" href="http://blogs.acceleration.net/birdman/">Nathan</a>'s suggestion, I tried changing this boilerplate mess to make the <code>pluginspace</code> and <code>codebase</code> attributes point to https.  That made IE stop throwing the error.  I'm not sure why it was downloading things from those URLs (as the  error message clearly stated), but now its happy, and my client's clients are no longer scared to use the site.
				
				<p>
				  But the fun doesn't end there.  I took a stress break and ran across a blog entry by <a href="http://www.jasongraphix.com">Jason</a> about his <a href="http://www.jasongraphix.com/archive/2006/04/activex_update">ActiveX update woes</a>.  Apparently to avoid paying licensing fees, Microsoft is changing how IE loads plugins (including flash), and unless developers (developers, developers, developers!) change how they render Flash, the users will be presented with a "Click here to activate this" dialog instead of just showing the flash.  
</p><p>
				  Apparently you have to "activate" a plugin before it will run.  More information can be found here: <a href="http://blog.deconcept.com/2005/12/15/internet-explorer-eolas-changes-and-the-flash-plugin/">Internet Explorer Eolas changes and the Flash plugin</a>.  
</p><p>
				  Like any good security measure, this can be instantly circumvented from the server (attacker) side.  Apparently if you set it up with javascript, then it doesn't need to be activated.  I guess there's no such thing as malicious javascript.  Microsoft has their workaround: <a href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/overview/activating_activex.asp ">activating ActiveX controls</a>, and the author of the helpful article above has a widely used Flash rendering javascript library that works too, called <a href="http://blog.deconcept.com/flashobject/">FlashObject</a>.  He's written a few books on flash, and his library looks pretty nice, both hiding the &lt;OBJECT&gt; mess and gracefully degrading to plain HTML if the flash plugin is absent.
				</p>
				<p>
				  Thanks Microsoft, thanks to your change (and Jason's post) I've discovered some nice open source library to remove a slurry of meaningless markup, but I would really prefer not to have to do your legal work.
				</p><img src ="http://blogs.acceleration.net/ryan/aggbug/2853.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Ryan</dc:creator><title>Getting a random sample with SQL Server 2000 revisted</title><link>http://blogs.acceleration.net/ryan/archive/2006/02/24/2832.aspx</link><pubDate>Fri, 24 Feb 2006 11:38:00 GMT</pubDate><guid>http://blogs.acceleration.net/ryan/archive/2006/02/24/2832.aspx</guid><description>&lt;p&gt;
				  I received a &lt;a href="http://blogs.acceleration.net/ryan/archive/2006/02/09/2820.aspx#2830"&gt;helpful comment&lt;/a&gt; on my &lt;a href="http://blogs.acceleration.net/ryan/archive/2006/02/09/2820.aspx"&gt;last entry&lt;/a&gt;, and sat down to try out this seemingly ideal 
				  solution:
				  &lt;/p&gt;&lt;div class="Code"&gt;
&lt;table class="dp-sql" border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;--limit results to @limit rows&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;SET&lt;/span&gt;&lt;span&gt; ROWCOUNT @limit &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;DELETE&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; #&lt;/span&gt;&lt;span class="keyword"&gt;temp&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;WHERE&lt;/span&gt;&lt;span&gt; Id &lt;/span&gt;&lt;span class="op"&gt;NOT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="op"&gt;IN&lt;/span&gt;&lt;span&gt;( &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="comment"&gt;--due to rowcount, this should be my random sample of @limit Ids&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;TOP&lt;/span&gt;&lt;span&gt; 100 PERCENT Id &lt;/span&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; Items &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;ORDER&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;BY&lt;/span&gt;&lt;span&gt; NEWID() &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;) &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="comment"&gt;--clear the rowcount, so results aren't limited&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;SET&lt;/span&gt;&lt;span&gt; ROWCOUNT 0 &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
				  &lt;/div&gt;
				  It didn't work, and I got really confused when I tried to figure out why, so I started making some
				simple tests.  
				
				&lt;h3&gt;Setup and basic test&lt;/h3&gt;
				&lt;p&gt;
				  I started by creating a table variable, and populating it with some data:
				  &lt;/p&gt;&lt;div class="Code"&gt;
&lt;table class="dp-sql" border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="keyword"&gt;DECLARE&lt;/span&gt;&lt;span&gt; @limiter &lt;/span&gt;&lt;span class="keyword"&gt;TABLE&lt;/span&gt;&lt;span&gt; (id &lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="op"&gt;not&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="op"&gt;null&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="comment"&gt;--get our set into storage&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;INSERT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;INTO&lt;/span&gt;&lt;span&gt; @limiter (id) ( &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;    &lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;TOP&lt;/span&gt;&lt;span&gt; 2000 Id &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;    &lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; Items &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;) &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
				  &lt;/div&gt;
				Next step, lets see if TOP 100 PERCENT works with ROWCOUNT the way I'd like it to:
				&lt;div class="Code"&gt;
&lt;table class="dp-sql" border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="keyword"&gt;SET&lt;/span&gt;&lt;span&gt; ROWCOUNT 10 &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;TOP&lt;/span&gt;&lt;span&gt; 100 PERCENT id &lt;/span&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; @limiter &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;    &lt;span class="keyword"&gt;ORDER&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;BY&lt;/span&gt;&lt;span&gt; NEWID() &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
				  &lt;/div&gt;
				Running this gives me 10 rows, and running it again give me 10 different rows, so my randomish requirement is met.
				  
				&lt;h3&gt;Subquery test&lt;/h3&gt;
				&lt;p&gt;
				  Next test is my goal, the randomish sample.  I make the 10 row random sample in a subquery, and then delete everything not in that sample.  Yes, this is kinda backwards, but the actual code is more complicated than my simplification here, so its easier to generate all the possibilities then remove all that don't fall into our sample.  
				  &lt;/p&gt;&lt;div class="Code"&gt;
				  &lt;table class="dp-sql" border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;--limit SELECT results&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;SET&lt;/span&gt;&lt;span&gt; ROWCOUNT 10 &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;DELETE&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; @limiter &lt;/span&gt;&lt;span class="keyword"&gt;WHERE&lt;/span&gt;&lt;span&gt; Id &lt;/span&gt;&lt;span class="op"&gt;NOT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="op"&gt;IN&lt;/span&gt;&lt;span&gt; ( &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;    &lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;TOP&lt;/span&gt;&lt;span&gt; 100 PERCENT id &lt;/span&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; @limiter &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;    &lt;span class="keyword"&gt;ORDER&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;BY&lt;/span&gt;&lt;span&gt; NEWID() &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;) &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="comment"&gt;--clear the rowcount, so results aren't limited&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;SET&lt;/span&gt;&lt;span&gt; ROWCOUNT 0 &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; * &lt;/span&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; @limiter &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
				  &lt;/div&gt;
				I expect this to return 10 rows.  It returns 2000, the full contents of @limiter.  That implies the TOP 100 PERCENT in the subquery returned the full 2000 rows, so nothing was deleted.  Checking the execution plan verifies this.  SET ROWCOUNT doesn't work on subqueries?  Or maybe the TOP 100 PERCENT is confusing SQL Server, so I'll try using a TOP N:
				&lt;div class="Code"&gt;
&lt;table class="dp-sql" border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="keyword"&gt;SET&lt;/span&gt;&lt;span&gt; ROWCOUNT 10 &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;DELETE&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; @limiter &lt;/span&gt;&lt;span class="keyword"&gt;WHERE&lt;/span&gt;&lt;span&gt; Id &lt;/span&gt;&lt;span class="op"&gt;NOT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="op"&gt;IN&lt;/span&gt;&lt;span&gt; ( &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;    &lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;TOP&lt;/span&gt;&lt;span&gt; 20000 id &lt;/span&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; @limiter &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;    &lt;span class="keyword"&gt;ORDER&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;BY&lt;/span&gt;&lt;span&gt; NEWID() &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;) &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="comment"&gt;--clear the rowcount, so results aren't limited&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;SET&lt;/span&gt;&lt;span&gt; ROWCOUNT 0 &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="func"&gt;COUNT&lt;/span&gt;&lt;span&gt;(id) &lt;/span&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; @limiter &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
				  &lt;/div&gt;
				Nope, still get 2000 rows in @limiter after the delete.  For grins, I start playing with the TOP statement, and get some confusing results:
				&lt;table border="1"&gt;
					 &lt;tr&gt;
						&lt;th&gt;TOP N&lt;/th&gt;&lt;th&gt;Rows left in @limiter&lt;/th&gt;
					 &lt;/tr&gt;
					 &lt;tr&gt;
						&lt;td&gt;TOP 20000&lt;/td&gt;&lt;td&gt;2000&lt;/td&gt;
					 &lt;/tr&gt;
					 &lt;tr&gt;
						&lt;td&gt;TOP 2000&lt;/td&gt;&lt;td&gt;2000&lt;/td&gt;
					 &lt;/tr&gt;
					 &lt;tr&gt;
						&lt;td&gt;TOP 1999&lt;/td&gt;&lt;td&gt;1999&lt;/td&gt;
					 &lt;/tr&gt;
					 &lt;tr&gt;
						&lt;td&gt;TOP 1998&lt;/td&gt;&lt;td&gt;1997&lt;/td&gt;
					 &lt;/tr&gt;
					 &lt;tr&gt;
						&lt;td colspan="2"&gt;Huh?  The top 1998 should have returned 1998 rows; the 2 rows not in that sample should have been deleted.  Lemme run that again to make sure I didn't mess up.&lt;/td&gt;
					 &lt;/tr&gt;
					 &lt;tr&gt;
						&lt;td&gt;TOP 1998&lt;/td&gt;&lt;td&gt;2000&lt;/td&gt;
					 &lt;/tr&gt;
					 &lt;tr&gt;
						&lt;td colspan="2"&gt;What the hell?  Is this some weird query caching thing? Let me run it a few more times...&lt;/td&gt;
					 &lt;/tr&gt;
					 &lt;tr&gt;
						&lt;td&gt;TOP 1998&lt;/td&gt;&lt;td&gt;1998&lt;/td&gt;
					 &lt;/tr&gt;
					 &lt;tr&gt;
						&lt;td&gt;TOP 1998&lt;/td&gt;&lt;td&gt;1999&lt;/td&gt;
					 &lt;/tr&gt;
					 &lt;tr&gt;
						&lt;td colspan="2"&gt;Seriously, WTF.  The execution plan just creates more questions:
						  &lt;img src="http://birdman.acceleration.net/ryan/top_bullshit.png" /&gt;
						  It's somehow processing 4M rows from a table variable with 2K rows!?  Then the TOP 1998 gets performed in the Filter operation, which reduces it to 1999 rows?  Ok, so 2K * 2K = 4M, so the WHERE Id NOT IN () is effectively performing a cross join, which makes sense, but why the 1999 rows?
					 &lt;/td&gt;&lt;/tr&gt;
					 &lt;tr&gt;
						&lt;td&gt;TOP 10&lt;/td&gt;&lt;td&gt;1990&lt;/td&gt;
					 &lt;/tr&gt;
				  &lt;/table&gt;
				Ok, so something is seriously inconsistent with ROWCOUNT and TOP in subqueries.  When I take the SET ROWCOUNT out, it still is inconsistent.  When I take out the ORDER BY NEWID(), it is still inconsistent.
				
				&lt;h3&gt;TOP in a subquery is broken?&lt;/h3&gt;
				&lt;p&gt;
				  Consider this repro:
				  &lt;/p&gt;&lt;div class="Code"&gt;
&lt;table class="dp-sql" border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="keyword"&gt;DECLARE&lt;/span&gt;&lt;span&gt; @t &lt;/span&gt;&lt;span class="keyword"&gt;TABLE&lt;/span&gt;&lt;span&gt; (id &lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="op"&gt;not&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="op"&gt;null&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;INSERT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;INTO&lt;/span&gt;&lt;span&gt; @t (id) ( &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;    &lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;TOP&lt;/span&gt;&lt;span&gt; 20 Id &lt;/span&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; [someTable] &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;) &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="func"&gt;COUNT&lt;/span&gt;&lt;span&gt;(Id) &lt;/span&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; @t &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;WHERE&lt;/span&gt;&lt;span&gt; Id &lt;/span&gt;&lt;span class="op"&gt;IN&lt;/span&gt;&lt;span&gt; ( &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;    &lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;TOP&lt;/span&gt;&lt;span&gt; 10 Id &lt;/span&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; @t &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;    &lt;span class="keyword"&gt;ORDER&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;BY&lt;/span&gt;&lt;span&gt; NEWID() &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;) &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
				  &lt;/div&gt;
				What do you think the count should be?  Hint: there's more than one answer.  Run that query repeatedly, and bask in inconsistency.  But... try this one:
				&lt;div class="Code"&gt;
				  &lt;table class="dp-sql" border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="func"&gt;COUNT&lt;/span&gt;&lt;span&gt;(Id) &lt;/span&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; [someTable] &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;WHERE&lt;/span&gt;&lt;span&gt; Id &lt;/span&gt;&lt;span class="op"&gt;IN&lt;/span&gt;&lt;span&gt; ( &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;    &lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;TOP&lt;/span&gt;&lt;span&gt; 10 Id &lt;/span&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; [someTable] &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;    &lt;span class="keyword"&gt;ORDER&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;BY&lt;/span&gt;&lt;span&gt; NEWID() &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;) &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
				&lt;/div&gt;
				And bam, we get 10 every time.  So its not TOP and ORDER BY in subqueries, maybe its something to do with table variables?  So, with that in mind, lets go back to the original test, but using a temp table instead of a table variable.
				
				&lt;h3&gt;Out with table variables&lt;/h3&gt;
				&lt;p&gt;
				  So, back to the beginning:
				  &lt;/p&gt;&lt;div class="Code"&gt;
&lt;table class="dp-sql" border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;TOP&lt;/span&gt;&lt;span&gt; 2000 Id &lt;/span&gt;&lt;span class="keyword"&gt;INTO&lt;/span&gt;&lt;span&gt; #limiter &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;    &lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; Items &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="comment"&gt;--limit SELECT results&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;SET&lt;/span&gt;&lt;span&gt; ROWCOUNT 10 &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;DELETE&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; #limiter &lt;/span&gt;&lt;span class="keyword"&gt;WHERE&lt;/span&gt;&lt;span&gt; Id &lt;/span&gt;&lt;span class="op"&gt;NOT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="op"&gt;IN&lt;/span&gt;&lt;span&gt; ( &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;    &lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;TOP&lt;/span&gt;&lt;span&gt; 100 PERCENT id &lt;/span&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; #limiter &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;    &lt;span class="keyword"&gt;ORDER&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;BY&lt;/span&gt;&lt;span&gt; NEWID() &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;) &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="comment"&gt;--clear the rowcount, so results aren't limited&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;SET&lt;/span&gt;&lt;span&gt; ROWCOUNT 0 &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="func"&gt;COUNT&lt;/span&gt;&lt;span&gt;(id) &lt;/span&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; #limiter &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
				  &lt;/div&gt;
				Result: 1990 rows.  It should have 10.  So, table variables aren't the problem.
				
				&lt;h3&gt;Fine, you win, SQL Server&lt;/h3&gt;
				&lt;p&gt;
				  Fine.  If you want it that badly MSSQL, you can have it.  I'll keep my slimy solution from the &lt;a href="http://blogs.acceleration.net/ryan/archive/2006/02/09/2820.aspx"&gt;last entry&lt;/a&gt; (for now), as you obviously don't want to let me do anything in a straighforward manner.  I'll try to forget the inconsistencies I found today, but it'll take time to heal.  Be patient with me.  And don't get all jealous if you see me installing &lt;a href="http://www.postgresql.org/"&gt;postgresql&lt;/a&gt; to see if it can do this better than you.  You know I'm locked in to you.
				&lt;/p&gt;&lt;img src ="http://blogs.acceleration.net/ryan/aggbug/2832.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>
				  I received a <a href="http://blogs.acceleration.net/ryan/archive/2006/02/09/2820.aspx#2830">helpful comment</a> on my <a href="http://blogs.acceleration.net/ryan/archive/2006/02/09/2820.aspx">last entry</a>, and sat down to try out this seemingly ideal 
				  solution:
				  </p><div class="Code">
<table class="dp-sql" border="0" cellpadding="0" cellspacing="0"><tbody><tr></tr><tr><td class="line"><span></span><span class="comment">--limit results to @limit rows</span><span> </span></td></tr><tr><td class="line"><span class="keyword">SET</span><span> ROWCOUNT @limit </span></td></tr><tr><td class="line"> </td></tr><tr><td class="line"><span class="keyword">DELETE</span><span> </span><span class="keyword">FROM</span><span> #</span><span class="keyword">temp</span><span> </span><span class="keyword">WHERE</span><span> Id </span><span class="op">NOT</span><span> </span><span class="op">IN</span><span>( </span></td></tr><tr><td class="line"><span class="comment">--due to rowcount, this should be my random sample of @limit Ids</span><span> </span></td></tr><tr><td class="line"><span class="keyword">SELECT</span><span> </span><span class="keyword">TOP</span><span> 100 PERCENT Id </span><span class="keyword">FROM</span><span> Items </span></td></tr><tr><td class="line"><span class="keyword">ORDER</span><span> </span><span class="keyword">BY</span><span> NEWID() </span></td></tr><tr><td class="line">) </td></tr><tr><td class="line"><span class="comment">--clear the rowcount, so results aren't limited</span><span> </span></td></tr><tr><td class="line"><span class="keyword">SET</span><span> ROWCOUNT 0 </span></td></tr></tbody></table>
				  </div>
				  It didn't work, and I got really confused when I tried to figure out why, so I started making some
				simple tests.  
				
				<h3>Setup and basic test</h3>
				<p>
				  I started by creating a table variable, and populating it with some data:
				  </p><div class="Code">
<table class="dp-sql" border="0" cellpadding="0" cellspacing="0"><tbody><tr></tr><tr><td class="line"><span></span><span class="keyword">DECLARE</span><span> @limiter </span><span class="keyword">TABLE</span><span> (id </span><span class="keyword">int</span><span> </span><span class="op">not</span><span> </span><span class="op">null</span><span>) </span></td></tr><tr><td class="line"><span class="comment">--get our set into storage</span><span> </span></td></tr><tr><td class="line"><span class="keyword">INSERT</span><span> </span><span class="keyword">INTO</span><span> @limiter (id) ( </span></td></tr><tr><td class="line">    <span class="keyword">SELECT</span><span> </span><span class="keyword">TOP</span><span> 2000 Id </span></td></tr><tr><td class="line">    <span class="keyword">FROM</span><span> Items </span></td></tr><tr><td class="line">) </td></tr></tbody></table>
				  </div>
				Next step, lets see if TOP 100 PERCENT works with ROWCOUNT the way I'd like it to:
				<div class="Code">
<table class="dp-sql" border="0" cellpadding="0" cellspacing="0"><tbody><tr></tr><tr><td class="line"><span></span><span class="keyword">SET</span><span> ROWCOUNT 10 </span></td></tr><tr><td class="line"> </td></tr><tr><td class="line"><span class="keyword">SELECT</span><span> </span><span class="keyword">TOP</span><span> 100 PERCENT id </span><span class="keyword">FROM</span><span> @limiter </span></td></tr><tr><td class="line">    <span class="keyword">ORDER</span><span> </span><span class="keyword">BY</span><span> NEWID() </span></td></tr></tbody></table>
				  </div>
				Running this gives me 10 rows, and running it again give me 10 different rows, so my randomish requirement is met.
				  
				<h3>Subquery test</h3>
				<p>
				  Next test is my goal, the randomish sample.  I make the 10 row random sample in a subquery, and then delete everything not in that sample.  Yes, this is kinda backwards, but the actual code is more complicated than my simplification here, so its easier to generate all the possibilities then remove all that don't fall into our sample.  
				  </p><div class="Code">
				  <table class="dp-sql" border="0" cellpadding="0" cellspacing="0"><tbody><tr></tr><tr><td class="line"><span></span><span class="comment">--limit SELECT results</span><span> </span></td></tr><tr><td class="line"><span class="keyword">SET</span><span> ROWCOUNT 10 </span></td></tr><tr><td class="line"> </td></tr><tr><td class="line"><span class="keyword">DELETE</span><span> </span><span class="keyword">FROM</span><span> @limiter </span><span class="keyword">WHERE</span><span> Id </span><span class="op">NOT</span><span> </span><span class="op">IN</span><span> ( </span></td></tr><tr><td class="line">    <span class="keyword">SELECT</span><span> </span><span class="keyword">TOP</span><span> 100 PERCENT id </span><span class="keyword">FROM</span><span> @limiter </span></td></tr><tr><td class="line">    <span class="keyword">ORDER</span><span> </span><span class="keyword">BY</span><span> NEWID() </span></td></tr><tr><td class="line">) </td></tr><tr><td class="line"> </td></tr><tr><td class="line"><span class="comment">--clear the rowcount, so results aren't limited</span><span> </span></td></tr><tr><td class="line"><span class="keyword">SET</span><span> ROWCOUNT 0 </span></td></tr><tr><td class="line"><span class="keyword">SELECT</span><span> * </span><span class="keyword">FROM</span><span> @limiter </span></td></tr></tbody></table>
				  </div>
				I expect this to return 10 rows.  It returns 2000, the full contents of @limiter.  That implies the TOP 100 PERCENT in the subquery returned the full 2000 rows, so nothing was deleted.  Checking the execution plan verifies this.  SET ROWCOUNT doesn't work on subqueries?  Or maybe the TOP 100 PERCENT is confusing SQL Server, so I'll try using a TOP N:
				<div class="Code">
<table class="dp-sql" border="0" cellpadding="0" cellspacing="0"><tbody><tr></tr><tr><td class="line"><span></span><span class="keyword">SET</span><span> ROWCOUNT 10 </span></td></tr><tr><td class="line"> </td></tr><tr><td class="line"><span class="keyword">DELETE</span><span> </span><span class="keyword">FROM</span><span> @limiter </span><span class="keyword">WHERE</span><span> Id </span><span class="op">NOT</span><span> </span><span class="op">IN</span><span> ( </span></td></tr><tr><td class="line">    <span class="keyword">SELECT</span><span> </span><span class="keyword">TOP</span><span> 20000 id </span><span class="keyword">FROM</span><span> @limiter </span></td></tr><tr><td class="line">    <span class="keyword">ORDER</span><span> </span><span class="keyword">BY</span><span> NEWID() </span></td></tr><tr><td class="line">) </td></tr><tr><td class="line"> </td></tr><tr><td class="line"><span class="comment">--clear the rowcount, so results aren't limited</span><span> </span></td></tr><tr><td class="line"><span class="keyword">SET</span><span> ROWCOUNT 0 </span></td></tr><tr><td class="line"><span class="keyword">SELECT</span><span> </span><span class="func">COUNT</span><span>(id) </span><span class="keyword">FROM</span><span> @limiter </span></td></tr></tbody></table>
				  </div>
				Nope, still get 2000 rows in @limiter after the delete.  For grins, I start playing with the TOP statement, and get some confusing results:
				<table border="1">
					 <tr>
						<th>TOP N</th><th>Rows left in @limiter</th>
					 </tr>
					 <tr>
						<td>TOP 20000</td><td>2000</td>
					 </tr>
					 <tr>
						<td>TOP 2000</td><td>2000</td>
					 </tr>
					 <tr>
						<td>TOP 1999</td><td>1999</td>
					 </tr>
					 <tr>
						<td>TOP 1998</td><td>1997</td>
					 </tr>
					 <tr>
						<td colspan="2">Huh?  The top 1998 should have returned 1998 rows; the 2 rows not in that sample should have been deleted.  Lemme run that again to make sure I didn't mess up.</td>
					 </tr>
					 <tr>
						<td>TOP 1998</td><td>2000</td>
					 </tr>
					 <tr>
						<td colspan="2">What the hell?  Is this some weird query caching thing? Let me run it a few more times...</td>
					 </tr>
					 <tr>
						<td>TOP 1998</td><td>1998</td>
					 </tr>
					 <tr>
						<td>TOP 1998</td><td>1999</td>
					 </tr>
					 <tr>
						<td colspan="2">Seriously, WTF.  The execution plan just creates more questions:
						  <img src="http://birdman.acceleration.net/ryan/top_bullshit.png" />
						  It's somehow processing 4M rows from a table variable with 2K rows!?  Then the TOP 1998 gets performed in the Filter operation, which reduces it to 1999 rows?  Ok, so 2K * 2K = 4M, so the WHERE Id NOT IN () is effectively performing a cross join, which makes sense, but why the 1999 rows?
					 </td></tr>
					 <tr>
						<td>TOP 10</td><td>1990</td>
					 </tr>
				  </table>
				Ok, so something is seriously inconsistent with ROWCOUNT and TOP in subqueries.  When I take the SET ROWCOUNT out, it still is inconsistent.  When I take out the ORDER BY NEWID(), it is still inconsistent.
				
				<h3>TOP in a subquery is broken?</h3>
				<p>
				  Consider this repro:
				  </p><div class="Code">
<table class="dp-sql" border="0" cellpadding="0" cellspacing="0"><tbody><tr></tr><tr><td class="line"><span></span><span class="keyword">DECLARE</span><span> @t </span><span class="keyword">TABLE</span><span> (id </span><span class="keyword">int</span><span> </span><span class="op">not</span><span> </span><span class="op">null</span><span>) </span></td></tr><tr><td class="line"> </td></tr><tr><td class="line"><span class="keyword">INSERT</span><span> </span><span class="keyword">INTO</span><span> @t (id) ( </span></td></tr><tr><td class="line">    <span class="keyword">SELECT</span><span> </span><span class="keyword">TOP</span><span> 20 Id </span><span class="keyword">FROM</span><span> [someTable] </span></td></tr><tr><td class="line">) </td></tr><tr><td class="line"> </td></tr><tr><td class="line"><span class="keyword">SELECT</span><span> </span><span class="func">COUNT</span><span>(Id) </span><span class="keyword">FROM</span><span> @t </span></td></tr><tr><td class="line"><span class="keyword">WHERE</span><span> Id </span><span class="op">IN</span><span> ( </span></td></tr><tr><td class="line">    <span class="keyword">SELECT</span><span> </span><span class="keyword">TOP</span><span> 10 Id </span><span class="keyword">FROM</span><span> @t </span></td></tr><tr><td class="line">    <span class="keyword">ORDER</span><span> </span><span class="keyword">BY</span><span> NEWID() </span></td></tr><tr><td class="line">) </td></tr></tbody></table>
				  </div>
				What do you think the count should be?  Hint: there's more than one answer.  Run that query repeatedly, and bask in inconsistency.  But... try this one:
				<div class="Code">
				  <table class="dp-sql" border="0" cellpadding="0" cellspacing="0"><tbody><tr></tr><tr><td class="line"><span></span><span class="keyword">SELECT</span><span> </span><span class="func">COUNT</span><span>(Id) </span><span class="keyword">FROM</span><span> [someTable] </span></td></tr><tr><td class="line"><span class="keyword">WHERE</span><span> Id </span><span class="op">IN</span><span> ( </span></td></tr><tr><td class="line">    <span class="keyword">SELECT</span><span> </span><span class="keyword">TOP</span><span> 10 Id </span><span class="keyword">FROM</span><span> [someTable] </span></td></tr><tr><td class="line">    <span class="keyword">ORDER</span><span> </span><span class="keyword">BY</span><span> NEWID() </span></td></tr><tr><td class="line">) </td></tr></tbody></table>
				</div>
				And bam, we get 10 every time.  So its not TOP and ORDER BY in subqueries, maybe its something to do with table variables?  So, with that in mind, lets go back to the original test, but using a temp table instead of a table variable.
				
				<h3>Out with table variables</h3>
				<p>
				  So, back to the beginning:
				  </p><div class="Code">
<table class="dp-sql" border="0" cellpadding="0" cellspacing="0"><tbody><tr></tr><tr><td class="line"><span></span><span class="keyword">SELECT</span><span> </span><span class="keyword">TOP</span><span> 2000 Id </span><span class="keyword">INTO</span><span> #limiter </span></td></tr><tr><td class="line">    <span class="keyword">FROM</span><span> Items </span></td></tr><tr><td class="line"> </td></tr><tr><td class="line"><span class="comment">--limit SELECT results</span><span> </span></td></tr><tr><td class="line"><span class="keyword">SET</span><span> ROWCOUNT 10 </span></td></tr><tr><td class="line"> </td></tr><tr><td class="line"><span class="keyword">DELETE</span><span> </span><span class="keyword">FROM</span><span> #limiter </span><span class="keyword">WHERE</span><span> Id </span><span class="op">NOT</span><span> </span><span class="op">IN</span><span> ( </span></td></tr><tr><td class="line">    <span class="keyword">SELECT</span><span> </span><span class="keyword">TOP</span><span> 100 PERCENT id </span><span class="keyword">FROM</span><span> #limiter </span></td></tr><tr><td class="line">    <span class="keyword">ORDER</span><span> </span><span class="keyword">BY</span><span> NEWID() </span></td></tr><tr><td class="line">) </td></tr><tr><td class="line"> </td></tr><tr><td class="line"><span class="comment">--clear the rowcount, so results aren't limited</span><span> </span></td></tr><tr><td class="line"><span class="keyword">SET</span><span> ROWCOUNT 0 </span></td></tr><tr><td class="line"><span class="keyword">SELECT</span><span> </span><span class="func">COUNT</span><span>(id) </span><span class="keyword">FROM</span><span> #limiter </span></td></tr></tbody></table>
				  </div>
				Result: 1990 rows.  It should have 10.  So, table variables aren't the problem.
				
				<h3>Fine, you win, SQL Server</h3>
				<p>
				  Fine.  If you want it that badly MSSQL, you can have it.  I'll keep my slimy solution from the <a href="http://blogs.acceleration.net/ryan/archive/2006/02/09/2820.aspx">last entry</a> (for now), as you obviously don't want to let me do anything in a straighforward manner.  I'll try to forget the inconsistencies I found today, but it'll take time to heal.  Be patient with me.  And don't get all jealous if you see me installing <a href="http://www.postgresql.org/">postgresql</a> to see if it can do this better than you.  You know I'm locked in to you.
				</p><img src ="http://blogs.acceleration.net/ryan/aggbug/2832.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Ryan</dc:creator><title>Getting a randomish sample with SQL Server 2000</title><link>http://blogs.acceleration.net/ryan/archive/2006/02/09/2820.aspx</link><pubDate>Thu, 09 Feb 2006 19:10:00 GMT</pubDate><guid>http://blogs.acceleration.net/ryan/archive/2006/02/09/2820.aspx</guid><description>&lt;p&gt;
				  I was recently presented with a seemingly simple task, write a query to return a random&lt;span style="color:blue;" title="for some values of random"&gt;*&lt;/span&gt; sample of rows
				  from a table, with the number of rows to pull determined at runtime.  
				  The surrounding problem is a bit more complex, but this was the specific task I was trying to accomplish,
				  and SQL Server 2000 didn't make it very easy.  The rest of my task involved deleting rows where the id wasn't in my random sample.
				&lt;/p&gt;
				&lt;h4&gt;First try, my almost-dream syntax&lt;/h4&gt;
				&lt;p&gt;My first attempt was a bit naive:
				&lt;/p&gt;&lt;div&gt;
&lt;table class="dp-sql" border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;TOP&lt;/span&gt;&lt;span&gt; @limit Id &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; Items &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;ORDER&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;BY&lt;/span&gt;&lt;span&gt; NEWID() &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
				&lt;/div&gt;
				&lt;code&gt;@limit&lt;/code&gt; is a variable which has how many rows I should be returning.
				I order by NEWID(), which makes a GUID for every row, as this is the best way I know of to get it ordered randomly.  I don't
				think its a terribly good way, but its the best I know.  If you have a better way, please comment or email.
			 
				&lt;p&gt;
				  That snippet will of course fail, giving this error message:
				&lt;/p&gt;&lt;div&gt;Incorrect syntax near '@limit'.&lt;/div&gt;
				Ok, so I can't dynamically set the TOP.  Fine.
			 
				&lt;h4&gt;Use ROWCOUNT&lt;/h4&gt;
				&lt;p&gt;
				  By using SET ROWCOUNT @limit, I could instruct SQL Server to only return @limit rows when performing a SELECT.  So, this was the query to 
				  delete rows not in my random sample:
				  &lt;/p&gt;&lt;div&gt;
&lt;table class="dp-sql" border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;--limit results to @limit rows&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;SET&lt;/span&gt;&lt;span&gt; ROWCOUNT @limit &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;DELETE&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; #&lt;/span&gt;&lt;span class="keyword"&gt;temp&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;WHERE&lt;/span&gt;&lt;span&gt; Id &lt;/span&gt;&lt;span class="op"&gt;NOT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="op"&gt;IN&lt;/span&gt;&lt;span&gt;( &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;    &lt;span class="comment"&gt;--due to rowcount, this should be my random sample of @limit Ids&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;    &lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; Id &lt;/span&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; Items &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;    &lt;span class="keyword"&gt;ORDER&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;BY&lt;/span&gt;&lt;span&gt; NEWID() &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;    ) &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="comment"&gt;--clear the rowcount, so results aren't limited&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;SET&lt;/span&gt;&lt;span&gt; ROWCOUNT 0 &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
				  &lt;/div&gt;
					That snippet also fails, giving this error:
				&lt;div class="Code"&gt;The ORDER BY clause is invalid in views, inline functions, derived tables, and subqueries, unless TOP is also specified.&lt;/div&gt;
				Ok, so I can't use ORDER BY in the subquery.  Well damn, that would have been really clean.  I could add a &lt;code&gt;TOP 2147483647&lt;/code&gt; in there, but that seemed like a bad idea.
				
				&lt;h4&gt;Use a table variable&lt;/h4&gt;
				&lt;p&gt;
				  Ok, next thought is to use a table variable, insert my rows in a random order, numbering each row, and then pull the rows with a number
				  below my limit:
				&lt;/p&gt;&lt;div&gt;
&lt;table class="dp-sql" border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;--make the table variable, the num column will count upwards as we insert, numbering the rows&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;DECLARE&lt;/span&gt;&lt;span&gt; @&lt;/span&gt;&lt;span class="keyword"&gt;temp&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;TABLE&lt;/span&gt;&lt;span&gt; (id &lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="op"&gt;NOT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="op"&gt;NULL&lt;/span&gt;&lt;span&gt;, num &lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="op"&gt;NOT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="op"&gt;NULL&lt;/span&gt;&lt;span&gt; IDENTITY(1,1)) &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="comment"&gt;--insert into the table in random order&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;INSERT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;INTO&lt;/span&gt;&lt;span&gt; @&lt;/span&gt;&lt;span class="keyword"&gt;temp&lt;/span&gt;&lt;span&gt; (id) &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;(&lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; Id  &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; Items &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;ORDER&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;BY&lt;/span&gt;&lt;span&gt; NEWID()) &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="comment"&gt;--get out our sample&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; Id &lt;/span&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; @&lt;/span&gt;&lt;span class="keyword"&gt;temp&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;WHERE&lt;/span&gt;&lt;span&gt; num &amp;lt;= @limit &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
				&lt;/div&gt;
				That snippet also fails, giving this error:
				&lt;div class="Code"&gt;Incorrect syntax near the keyword 'ORDER'.&lt;/div&gt;
				Oh right, I can't use ORDER BY in the subquery.  Fine.
				
				&lt;h4&gt;Use a temporary table and INSERT INTO&lt;/h4&gt;
				&lt;p&gt;
				  I was trying to avoid temporary tables, since they have some performance issues, but figured maybe there wasn't any other way.  So,
				  I broke down and used a temp table:
				  &lt;/p&gt;&lt;div&gt;
				  &lt;table class="dp-sql" border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;--select into the temp table, using IDENTITY to get my row counter&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; Id, IDENTITY(&lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;, 1,1) [num] &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;INTO&lt;/span&gt;&lt;span&gt; #&lt;/span&gt;&lt;span class="keyword"&gt;temp&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; Items &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;ORDER&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;BY&lt;/span&gt;&lt;span&gt; NEWID() &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="comment"&gt;--get out our sample&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; Id &lt;/span&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; #&lt;/span&gt;&lt;span class="keyword"&gt;temp&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;WHERE&lt;/span&gt;&lt;span&gt; num &amp;lt; @limit &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="comment"&gt;--clean up&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;DROP&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;TABLE&lt;/span&gt;&lt;span&gt; #&lt;/span&gt;&lt;span class="keyword"&gt;temp&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
				  &lt;/div&gt;
				That snippet also fails, giving this error:
				&lt;div class="Code"&gt;Cannot add identity column, using the SELECT INTO statement, to table '#temp', which already has column 'Id' that inherits the identity property.&lt;/div&gt;
				Ok... So the 'identity' property gets inherited into the temp table, and so I can't specify another identity column.  
				I did some searching in the docs, and there didn't seem to be a way to get an autoincrement field without it
				being an identity field.  Ok, fine, I know a retarded way to get around that.
				
				&lt;h4&gt;Use a temporary table, INSERT INTO, and a table variable to mask the identity column&lt;/h4&gt;
				&lt;p&gt;
				  I actually wrote a variant of this:
				  &lt;/p&gt;&lt;div&gt;
				  &lt;table class="dp-sql" border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;--Make a table to copy my ids into&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;DECLARE&lt;/span&gt;&lt;span&gt; @retarded &lt;/span&gt;&lt;span class="keyword"&gt;TABLE&lt;/span&gt;&lt;span&gt; (id &lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="comment"&gt;--copy all my ids in, but leave the 'identity' property behind&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;INSERT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;INTO&lt;/span&gt;&lt;span&gt; @retarded (id) &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;    (&lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; Id &lt;/span&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; Items) &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="comment"&gt;--select into the temp table, using IDENTITY to get my row counter&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; Id, IDENTITY(&lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;, 1,1) [num] &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;INTO&lt;/span&gt;&lt;span&gt; #&lt;/span&gt;&lt;span class="keyword"&gt;temp&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; @retarded &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;ORDER&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;BY&lt;/span&gt;&lt;span&gt; NEWID() &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="comment"&gt;--get out our sample&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; Id &lt;/span&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; #&lt;/span&gt;&lt;span class="keyword"&gt;temp&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;WHERE&lt;/span&gt;&lt;span&gt; num &amp;lt; @limit &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="comment"&gt;--clean up&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;DROP&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;TABLE&lt;/span&gt;&lt;span&gt; #&lt;/span&gt;&lt;span class="keyword"&gt;temp&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
				  &lt;/div&gt;
				  This worked, but made me sick to my stomach.  There &lt;em&gt;had&lt;/em&gt; to be a better way.
				
				&lt;h4&gt;Use a temporary table, INSERT INTO, and a dummy expression&lt;/h4&gt;
				&lt;p&gt;
				  So, I dug through some more documentation, finding this gem:
				  &lt;/p&gt;&lt;blockquote&gt;
				  When an existing identity column is selected into a new table, the new column inherits the IDENTITY property, unless one of the following conditions is true: 
				  &lt;ul&gt;
					 &lt;li&gt;The SELECT statement contains a join, GROUP BY clause, or aggregate function.&lt;/li&gt;
					 &lt;li&gt;Multiple SELECT statements are joined by using UNION.&lt;/li&gt;
					 &lt;li&gt;The identity column is listed more than one time in the select list.&lt;/li&gt;
					 &lt;li&gt;The identity column is part of an expression.&lt;/li&gt;
				  &lt;/ul&gt;
				  If any one of these conditions is true, the column is created NOT NULL instead of inheriting the IDENTITY property. All rules and restrictions for the identity columns apply to the new table.
				&lt;/blockquote&gt;
				Ok, so I decided the least despicable thing to do would be to make a dummy expression to drop the identity property:
				&lt;div class="Code"&gt;
&lt;table class="dp-sql" border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;--select into the temp table, using IDENTITY to get my row counter&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; Id*1 [Id], IDENTITY(&lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;, 1,1) [num] &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;INTO&lt;/span&gt;&lt;span&gt; #&lt;/span&gt;&lt;span class="keyword"&gt;temp&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; Items &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;ORDER&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;BY&lt;/span&gt;&lt;span&gt; NEWID() &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="comment"&gt;--get out our sample&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;SELECT&lt;/span&gt;&lt;span&gt; Id &lt;/span&gt;&lt;span class="keyword"&gt;FROM&lt;/span&gt;&lt;span&gt; #&lt;/span&gt;&lt;span class="keyword"&gt;temp&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;WHERE&lt;/span&gt;&lt;span&gt; num &amp;lt; @limit &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="comment"&gt;--clean up&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;DROP&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="keyword"&gt;TABLE&lt;/span&gt;&lt;span&gt; #&lt;/span&gt;&lt;span class="keyword"&gt;temp&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
				  &lt;/div&gt;
				I did some profiling, and doing &lt;code&gt;id*1&lt;/code&gt; was the same as doing &lt;code&gt;id+0&lt;/code&gt;, so I left it as multiplication.
				  
				&lt;p&gt;
				  All in all, very, very frustrating, and I'm not sure if the &lt;code&gt;TOP 2147483647&lt;/code&gt; option above is worse than the hack at the end.  Votes are welcome.&lt;br /&gt;&lt;br /&gt;

				  I hate how much I jump through hoops and reinvent to do what should be very simple tasks.  
				  I mean, c'mon, we've been programming for over 50 years now, and I'm pretty sure pulling a random sample from a dataset is
				  not a new task.  We should be better than this.
				&lt;/p&gt;&lt;img src ="http://blogs.acceleration.net/ryan/aggbug/2820.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>
				  I was recently presented with a seemingly simple task, write a query to return a random<span style="color:blue;" title="for some values of random">*</span> sample of rows
				  from a table, with the number of rows to pull determined at runtime.  
				  The surrounding problem is a bit more complex, but this was the specific task I was trying to accomplish,
				  and SQL Server 2000 didn't make it very easy.  The rest of my task involved deleting rows where the id wasn't in my random sample.
				</p>
				<h4>First try, my almost-dream syntax</h4>
				<p>My first attempt was a bit naive:
				</p><div>
<table class="dp-sql" border="0" cellpadding="0" cellspacing="0"><tbody><tr></tr><tr><td class="line"><span></span><span class="keyword">SELECT</span><span> </span><span class="keyword">TOP</span><span> @limit Id </span></td></tr><tr><td class="line"><span class="keyword">FROM</span><span> Items </span></td></tr><tr><td class="line"><span class="keyword">ORDER</span><span> </span><span class="keyword">BY</span><span> NEWID() </span></td></tr></tbody></table>
				</div>
				<code>@limit</code> is a variable which has how many rows I should be returning.
				I order by NEWID(), which makes a GUID for every row, as this is the best way I know of to get it ordered randomly.  I don't
				think its a terribly good way, but its the best I know.  If you have a better way, please comment or email.
			 
				<p>
				  That snippet will of course fail, giving this error message:
				</p><div>Incorrect syntax near '@limit'.</div>
				Ok, so I can't dynamically set the TOP.  Fine.
			 
				<h4>Use ROWCOUNT</h4>
				<p>
				  By using SET ROWCOUNT @limit, I could instruct SQL Server to only return @limit rows when performing a SELECT.  So, this was the query to 
				  delete rows not in my random sample:
				  </p><div>
<table class="dp-sql" border="0" cellpadding="0" cellspacing="0"><tbody><tr></tr><tr><td class="line"><span></span><span class="comment">--limit results to @limit rows</span><span> </span></td></tr><tr><td class="line"><span class="keyword">SET</span><span> ROWCOUNT @limit </span></td></tr><tr><td class="line"> </td></tr><tr><td class="line"><span class="keyword">DELETE</span><span> </span><span class="keyword">FROM</span><span> #</span><span class="keyword">temp</span><span> </span><span class="keyword">WHERE</span><span> Id </span><span class="op">NOT</span><span> </span><span class="op">IN</span><span>( </span></td></tr><tr><td class="line">    <span class="comment">--due to rowcount, this should be my random sample of @limit Ids</span><span> </span></td></tr><tr><td class="line">    <span class="keyword">SELECT</span><span> Id </span><span class="keyword">FROM</span><span> Items </span></td></tr><tr><td class="line">    <span class="keyword">ORDER</span><span> </span><span class="keyword">BY</span><span> NEWID() </span></td></tr><tr><td class="line">    ) </td></tr><tr><td class="line"><span class="comment">--clear the rowcount, so results aren't limited</span><span> </span></td></tr><tr><td class="line"><span class="keyword">SET</span><span> ROWCOUNT 0 </span></td></tr></tbody></table>
				  </div>
					That snippet also fails, giving this error:
				<div class="Code">The ORDER BY clause is invalid in views, inline functions, derived tables, and subqueries, unless TOP is also specified.</div>
				Ok, so I can't use ORDER BY in the subquery.  Well damn, that would have been really clean.  I could add a <code>TOP 2147483647</code> in there, but that seemed like a bad idea.
				
				<h4>Use a table variable</h4>
				<p>
				  Ok, next thought is to use a table variable, insert my rows in a random order, numbering each row, and then pull the rows with a number
				  below my limit:
				</p><div>
<table class="dp-sql" border="0" cellpadding="0" cellspacing="0"><tbody><tr></tr><tr><td class="line"><span></span><span class="comment">--make the table variable, the num column will count upwards as we insert, numbering the rows</span><span> </span></td></tr><tr><td class="line"><span class="keyword">DECLARE</span><span> @</span><span class="keyword">temp</span><span> </span><span class="keyword">TABLE</span><span> (id </span><span class="keyword">int</span><span> </span><span class="op">NOT</span><span> </span><span class="op">NULL</span><span>, num </span><span class="keyword">int</span><span> </span><span class="op">NOT</span><span> </span><span class="op">NULL</span><span> IDENTITY(1,1)) </span></td></tr><tr><td class="line"> </td></tr><tr><td class="line"><span class="comment">--insert into the table in random order</span><span> </span></td></tr><tr><td class="line"><span class="keyword">INSERT</span><span> </span><span class="keyword">INTO</span><span> @</span><span class="keyword">temp</span><span> (id) </span></td></tr><tr><td class="line">(<span class="keyword">SELECT</span><span> Id  </span></td></tr><tr><td class="line"><span class="keyword">FROM</span><span> Items </span></td></tr><tr><td class="line"><span class="keyword">ORDER</span><span> </span><span class="keyword">BY</span><span> NEWID()) </span></td></tr><tr><td class="line"> </td></tr><tr><td class="line"><span class="comment">--get out our sample</span><span> </span></td></tr><tr><td class="line"><span class="keyword">SELECT</span><span> Id </span><span class="keyword">FROM</span><span> @</span><span class="keyword">temp</span><span> </span><span class="keyword">WHERE</span><span> num &lt;= @limit </span></td></tr></tbody></table>
				</div>
				That snippet also fails, giving this error:
				<div class="Code">Incorrect syntax near the keyword 'ORDER'.</div>
				Oh right, I can't use ORDER BY in the subquery.  Fine.
				
				<h4>Use a temporary table and INSERT INTO</h4>
				<p>
				  I was trying to avoid temporary tables, since they have some performance issues, but figured maybe there wasn't any other way.  So,
				  I broke down and used a temp table:
				  </p><div>
				  <table class="dp-sql" border="0" cellpadding="0" cellspacing="0"><tbody><tr></tr><tr><td class="line"><span></span><span class="comment">--select into the temp table, using IDENTITY to get my row counter</span><span> </span></td></tr><tr><td class="line"><span class="keyword">SELECT</span><span> Id, IDENTITY(</span><span class="keyword">int</span><span>, 1,1) [num] </span></td></tr><tr><td class="line"><span class="keyword">INTO</span><span> #</span><span class="keyword">temp</span><span>  </span></td></tr><tr><td class="line"><span class="keyword">FROM</span><span> Items </span></td></tr><tr><td class="line"><span class="keyword">ORDER</span><span> </span><span class="keyword">BY</span><span> NEWID() </span></td></tr><tr><td class="line"> </td></tr><tr><td class="line"><span class="comment">--get out our sample</span><span> </span></td></tr><tr><td class="line"><span class="keyword">SELECT</span><span> Id </span><span class="keyword">FROM</span><span> #</span><span class="keyword">temp</span><span> </span><span class="keyword">WHERE</span><span> num &lt; @limit </span></td></tr><tr><td class="line"> </td></tr><tr><td class="line"><span class="comment">--clean up</span><span> </span></td></tr><tr><td class="line"><span class="keyword">DROP</span><span> </span><span class="keyword">TABLE</span><span> #</span><span class="keyword">temp</span><span> </span></td></tr></tbody></table>
				  </div>
				That snippet also fails, giving this error:
				<div class="Code">Cannot add identity column, using the SELECT INTO statement, to table '#temp', which already has column 'Id' that inherits the identity property.</div>
				Ok... So the 'identity' property gets inherited into the temp table, and so I can't specify another identity column.  
				I did some searching in the docs, and there didn't seem to be a way to get an autoincrement field without it
				being an identity field.  Ok, fine, I know a retarded way to get around that.
				
				<h4>Use a temporary table, INSERT INTO, and a table variable to mask the identity column</h4>
				<p>
				  I actually wrote a variant of this:
				  </p><div>
				  <table class="dp-sql" border="0" cellpadding="0" cellspacing="0"><tbody><tr></tr><tr><td class="line"><span></span><span class="comment">--Make a table to copy my ids into</span><span> </span></td></tr><tr><td class="line"><span class="keyword">DECLARE</span><span> @retarded </span><span class="keyword">TABLE</span><span> (id </span><span class="keyword">int</span><span>) </span></td></tr><tr><td class="line"> </td></tr><tr><td class="line"><span class="comment">--copy all my ids in, but leave the 'identity' property behind</span><span> </span></td></tr><tr><td class="line"><span class="keyword">INSERT</span><span> </span><span class="keyword">INTO</span><span> @retarded (id) </span></td></tr><tr><td class="line">    (<span class="keyword">SELECT</span><span> Id </span><span class="keyword">FROM</span><span> Items) </span></td></tr><tr><td class="line"> </td></tr><tr><td class="line"><span class="comment">--select into the temp table, using IDENTITY to get my row counter</span><span> </span></td></tr><tr><td class="line"><span class="keyword">SELECT</span><span> Id, IDENTITY(</span><span class="keyword">int</span><span>, 1,1) [num] </span></td></tr><tr><td class="line"><span class="keyword">INTO</span><span> #</span><span class="keyword">temp</span><span>  </span></td></tr><tr><td class="line"><span class="keyword">FROM</span><span> @retarded </span></td></tr><tr><td class="line"><span class="keyword">ORDER</span><span> </span><span class="keyword">BY</span><span> NEWID() </span></td></tr><tr><td class="line"> </td></tr><tr><td class="line"><span class="comment">--get out our sample</span><span> </span></td></tr><tr><td class="line"><span class="keyword">SELECT</span><span> Id </span><span class="keyword">FROM</span><span> #</span><span class="keyword">temp</span><span> </span><span class="keyword">WHERE</span><span> num &lt; @limit </span></td></tr><tr><td class="line"> </td></tr><tr><td class="line"><span class="comment">--clean up</span><span> </span></td></tr><tr><td class="line"><span class="keyword">DROP</span><span> </span><span class="keyword">TABLE</span><span> #</span><span class="keyword">temp</span><span> </span></td></tr></tbody></table>
				  </div>
				  This worked, but made me sick to my stomach.  There <em>had</em> to be a better way.
				
				<h4>Use a temporary table, INSERT INTO, and a dummy expression</h4>
				<p>
				  So, I dug through some more documentation, finding this gem:
				  </p><blockquote>
				  When an existing identity column is selected into a new table, the new column inherits the IDENTITY property, unless one of the following conditions is true: 
				  <ul>
					 <li>The SELECT statement contains a join, GROUP BY clause, or aggregate function.</li>
					 <li>Multiple SELECT statements are joined by using UNION.</li>
					 <li>The identity column is listed more than one time in the select list.</li>
					 <li>The identity column is part of an expression.</li>
				  </ul>
				  If any one of these conditions is true, the column is created NOT NULL instead of inheriting the IDENTITY property. All rules and restrictions for the identity columns apply to the new table.
				</blockquote>
				Ok, so I decided the least despicable thing to do would be to make a dummy expression to drop the identity property:
				<div class="Code">
<table class="dp-sql" border="0" cellpadding="0" cellspacing="0"><tbody><tr></tr><tr><td class="line"><span></span><span class="comment">--select into the temp table, using IDENTITY to get my row counter</span><span> </span></td></tr><tr><td class="line"><span class="keyword">SELECT</span><span> Id*1 [Id], IDENTITY(</span><span class="keyword">int</span><span>, 1,1) [num] </span></td></tr><tr><td class="line"><span class="keyword">INTO</span><span> #</span><span class="keyword">temp</span><span>  </span></td></tr><tr><td class="line"><span class="keyword">FROM</span><span> Items </span></td></tr><tr><td class="line"><span class="keyword">ORDER</span><span> </span><span class="keyword">BY</span><span> NEWID() </span></td></tr><tr><td class="line"> </td></tr><tr><td class="line"><span class="comment">--get out our sample</span><span> </span></td></tr><tr><td class="line"><span class="keyword">SELECT</span><span> Id </span><span class="keyword">FROM</span><span> #</span><span class="keyword">temp</span><span> </span><span class="keyword">WHERE</span><span> num &lt; @limit </span></td></tr><tr><td class="line"> </td></tr><tr><td class="line"><span class="comment">--clean up</span><span> </span></td></tr><tr><td class="line"><span class="keyword">DROP</span><span> </span><span class="keyword">TABLE</span><span> #</span><span class="keyword">temp</span><span> </span></td></tr></tbody></table>
				  </div>
				I did some profiling, and doing <code>id*1</code> was the same as doing <code>id+0</code>, so I left it as multiplication.
				  
				<p>
				  All in all, very, very frustrating, and I'm not sure if the <code>TOP 2147483647</code> option above is worse than the hack at the end.  Votes are welcome.<br /><br />

				  I hate how much I jump through hoops and reinvent to do what should be very simple tasks.  
				  I mean, c'mon, we've been programming for over 50 years now, and I'm pretty sure pulling a random sample from a dataset is
				  not a new task.  We should be better than this.
				</p><img src ="http://blogs.acceleration.net/ryan/aggbug/2820.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Ryan</dc:creator><title>Crystal Reports 9 Database login prompt</title><link>http://blogs.acceleration.net/ryan/archive/2005/12/15/2809.aspx</link><pubDate>Thu, 15 Dec 2005 13:20:00 GMT</pubDate><guid>http://blogs.acceleration.net/ryan/archive/2005/12/15/2809.aspx</guid><description>&lt;p&gt;
				  One client of mine uses Crystal Reports for reporting, and our experience has been pretty bad overall.  Part of 
				  that might be due to the guy my client hired to create all of them.  He seemed like a nice enough guy, but suffice
				  to say when I was asked to start replacing the Crystal Reports in our existing system there was talk of lawsuits.  Every 
				  report was made using the design view, and they had a funky web interface with really bad UI displaying all the reports.
				&lt;/p&gt;
				&lt;p&gt;
				  Anyway, we had SQL Server replication set up, and then the Crystal Reports were looking at a seperate database server, as
				  they were designed in such a way to be enormously inefficient.  So, when replication decided to crap itself, we switched over
				  to log shipping, thinking everything would just keep working.  One of the many problems that cropped up was the appearance 
				  of a database login prompt:
				&lt;/p&gt;
				&lt;div align="center"&gt;
				  &lt;img src="http://birdman.acceleration.net/ryan/crystal_prompt.png" /&gt;
				&lt;/div&gt;
				&lt;p&gt;
				  We tried changing the connection information in the Crystal designer, and the Crystal designer would always pull up a report just fine.
				  The damn web interface would always prompt for information.  We'd put in the information we entered in the designer, and then
				  it would work.  Since we didn't want to have users entering a user/pass every time they wanted to see a report, we kept changing
				  things, trying to find something that would work.  Finally we found that it would work if we pointed the report at our live database
				  server, and ignore the backup we made for Crystal to use.  As a temporary solution, we started changing all the reports to look
				  at the other server, and googled like mad to try to find a solution.
				&lt;/p&gt;
				&lt;p&gt;
				  After finding many, many people having this problem unresolved, and many, many solutions that are applicable if you're coding these
				  up by hand, but nothing for our problem.  We could tell that it was using the wrong config information, but had no idea how to 
				  change what it was using.
				&lt;/p&gt;
				&lt;h2&gt;Solution&lt;/h2&gt;
				&lt;p&gt;
				  The solution came after Chris did a text search on the web server, and found some random ASP file where the user info was stored:
				&lt;/p&gt;
				&lt;div class="code"&gt;
				  %webroot%\ASP\rPortfolio\HTMLViewers\interactiveViewer.asp
				&lt;/div&gt;
				&lt;p&gt;
				  The username and password for the web interface was hardcoded there, and we couldn't find anything in Crystal that could change it.  
				  Notepad worked just fine.  So, I guess for the web viewer, Crystal silently ignores the settings in the individual reports, and just
				  uses that one.  Great design.
				&lt;/p&gt;&lt;img src ="http://blogs.acceleration.net/ryan/aggbug/2809.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>
				  One client of mine uses Crystal Reports for reporting, and our experience has been pretty bad overall.  Part of 
				  that might be due to the guy my client hired to create all of them.  He seemed like a nice enough guy, but suffice
				  to say when I was asked to start replacing the Crystal Reports in our existing system there was talk of lawsuits.  Every 
				  report was made using the design view, and they had a funky web interface with really bad UI displaying all the reports.
				</p>
				<p>
				  Anyway, we had SQL Server replication set up, and then the Crystal Reports were looking at a seperate database server, as
				  they were designed in such a way to be enormously inefficient.  So, when replication decided to crap itself, we switched over
				  to log shipping, thinking everything would just keep working.  One of the many problems that cropped up was the appearance 
				  of a database login prompt:
				</p>
				<div align="center">
				  <img src="http://birdman.acceleration.net/ryan/crystal_prompt.png" />
				</div>
				<p>
				  We tried changing the connection information in the Crystal designer, and the Crystal designer would always pull up a report just fine.
				  The damn web interface would always prompt for information.  We'd put in the information we entered in the designer, and then
				  it would work.  Since we didn't want to have users entering a user/pass every time they wanted to see a report, we kept changing
				  things, trying to find something that would work.  Finally we found that it would work if we pointed the report at our live database
				  server, and ignore the backup we made for Crystal to use.  As a temporary solution, we started changing all the reports to look
				  at the other server, and googled like mad to try to find a solution.
				</p>
				<p>
				  After finding many, many people having this problem unresolved, and many, many solutions that are applicable if you're coding these
				  up by hand, but nothing for our problem.  We could tell that it was using the wrong config information, but had no idea how to 
				  change what it was using.
				</p>
				<h2>Solution</h2>
				<p>
				  The solution came after Chris did a text search on the web server, and found some random ASP file where the user info was stored:
				</p>
				<div class="code">
				  %webroot%\ASP\rPortfolio\HTMLViewers\interactiveViewer.asp
				</div>
				<p>
				  The username and password for the web interface was hardcoded there, and we couldn't find anything in Crystal that could change it.  
				  Notepad worked just fine.  So, I guess for the web viewer, Crystal silently ignores the settings in the individual reports, and just
				  uses that one.  Great design.
				</p><img src ="http://blogs.acceleration.net/ryan/aggbug/2809.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Ryan</dc:creator><title>Contributing to Firefox cont.</title><link>http://blogs.acceleration.net/ryan/archive/2005/12/15/2807.aspx</link><pubDate>Thu, 15 Dec 2005 09:29:00 GMT</pubDate><guid>http://blogs.acceleration.net/ryan/archive/2005/12/15/2807.aspx</guid><description>&lt;p&gt;
				  A few weeks ago I wrote about &lt;a href="http://blogs.acceleration.net/ryan/archive/2005/11/30/2805.aspx"&gt;Contributing to Firefox on WinXP&lt;/a&gt;,
				  and last night, my patch got committed to the trunk!  Whenever the next Firefox point release comes out, millions of people
				  will be using the simple for loop that I wrote.  Here's how the process worked:
				&lt;/p&gt;
				&lt;ol&gt;
				  &lt;li&gt;11-30-2005: submitted patch and requested review&lt;/li&gt;
				  &lt;li&gt;12-04-2005: passed review&lt;/li&gt;
				  &lt;li&gt;12-14-2005: I politely asked around on &lt;a href="irc://irc.mozilla.org/xul"&gt;#xul&lt;/a&gt; and 
					 &lt;a href="irc://irc.mozilla.org/developers"&gt;#developers&lt;/a&gt; if there was anything else I was expected to do 
					 before the patch was committed.  I was told to email the reviewer or make a comment on the bug.  I opted to make
					 a comment on the bug.&lt;/li&gt;
				  &lt;li&gt;12-14-2005: Gavin Sharp replied to my comment apologizing for the delay, and committed my patch.&lt;/li&gt;
				&lt;/ol&gt;
				&lt;p&gt;
				  So, except for the 10-day delay and slight confusion over my role, I'd say it went pretty smoothly.  This experience
				  certainly encourages me to make more contributions.  I've been using 
				  &lt;a href="http://www.mozilla.org/projects/calendar/sunbird.html"&gt;Sunbird&lt;/a&gt; for calendar stuff, and have seen a few minor
				  glitches in that, maybe I'll toss in a patch or two there next.
				&lt;/p&gt;&lt;img src ="http://blogs.acceleration.net/ryan/aggbug/2807.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>
				  A few weeks ago I wrote about <a href="http://blogs.acceleration.net/ryan/archive/2005/11/30/2805.aspx">Contributing to Firefox on WinXP</a>,
				  and last night, my patch got committed to the trunk!  Whenever the next Firefox point release comes out, millions of people
				  will be using the simple for loop that I wrote.  Here's how the process worked:
				</p>
				<ol>
				  <li>11-30-2005: submitted patch and requested review</li>
				  <li>12-04-2005: passed review</li>
				  <li>12-14-2005: I politely asked around on <a href="irc://irc.mozilla.org/xul">#xul</a> and 
					 <a href="irc://irc.mozilla.org/developers">#developers</a> if there was anything else I was expected to do 
					 before the patch was committed.  I was told to email the reviewer or make a comment on the bug.  I opted to make
					 a comment on the bug.</li>
				  <li>12-14-2005: Gavin Sharp replied to my comment apologizing for the delay, and committed my patch.</li>
				</ol>
				<p>
				  So, except for the 10-day delay and slight confusion over my role, I'd say it went pretty smoothly.  This experience
				  certainly encourages me to make more contributions.  I've been using 
				  <a href="http://www.mozilla.org/projects/calendar/sunbird.html">Sunbird</a> for calendar stuff, and have seen a few minor
				  glitches in that, maybe I'll toss in a patch or two there next.
				</p><img src ="http://blogs.acceleration.net/ryan/aggbug/2807.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Ryan</dc:creator><title>Contributing to Firefox on WinXP</title><link>http://blogs.acceleration.net/ryan/archive/2005/11/30/2805.aspx</link><pubDate>Wed, 30 Nov 2005 12:54:00 GMT</pubDate><guid>http://blogs.acceleration.net/ryan/archive/2005/11/30/2805.aspx</guid><description>&lt;p&gt;
				  In the process of converting my remote XUL apps to use Firefox 1.5, I found a bug in &lt;code&gt;&amp;lt;tree&amp;gt;&lt;/code&gt;.
				  The column picker breaks when you've added things to Array.prototype.  That took many hours to find, after removing and re-adding
				  countless lines of XUL and javascript.  It came down to some functions we were adding to Array.prototype in one of
				  our libraries.  When I commented those out, it worked just fine.  I installed the 
				  &lt;a href="http://forums.mozillazine.org/viewtopic.php?t=318102"&gt;Console&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; extension, which gives some better
				  error reporting, and found the a javascript error occurring in a file called &lt;code&gt;tree.xml&lt;/code&gt;.  It was a mess of XBL,
				  but the problem was apparent.
				&lt;/p&gt;
				
				The orignal code:
				&lt;div class="CodeBlock"&gt;

				  &lt;table class="dp-c" border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="keyword"&gt;var&lt;/span&gt;&lt;span&gt; hidden = !tree.enableColumnDrag; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;const&lt;/span&gt;&lt;span&gt; anonids = [&lt;/span&gt;&lt;span class="string"&gt;"menuseparator"&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class="string"&gt;"menuitem"&lt;/span&gt;&lt;span&gt;]; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class="keyword"&gt;var&lt;/span&gt;&lt;span&gt; anonid &lt;/span&gt;&lt;span class="keyword"&gt;in&lt;/span&gt;&lt;span&gt; anonids) { &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;  &lt;span class="keyword"&gt;var&lt;/span&gt;&lt;span&gt; element = document.getAnonymousElementByAttribute(&lt;/span&gt;&lt;span class="keyword"&gt;this&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class="string"&gt;"anonid"&lt;/span&gt;&lt;span&gt;, anonids[anonid]); &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;  element.hidden = hidden; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;} &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
				&lt;/div&gt;
				&lt;p&gt;
				  The problem is the usage of &lt;code&gt;in&lt;/code&gt;.  &lt;code&gt;in&lt;/code&gt; is rather introspective, and  will iterate over all 
				  the properties on the object, including user-added functions.  
				  My guess is the author of this code is used to the Python &lt;code&gt;in&lt;/code&gt; keyword, which
				  just iterates over the values in the object.  I figure changing that to not use the in keyword should solve the problem:
				&lt;/p&gt;
				&lt;div class="CodeBlock"&gt;
				  &lt;table class="dp-c" border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="keyword"&gt;var&lt;/span&gt;&lt;span&gt; hidden = !tree.enableColumnDrag; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;const&lt;/span&gt;&lt;span&gt; anonids = [&lt;/span&gt;&lt;span class="string"&gt;"menuseparator"&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class="string"&gt;"menuitem"&lt;/span&gt;&lt;span&gt;]; &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;&lt;span class="keyword"&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class="keyword"&gt;var&lt;/span&gt;&lt;span&gt; i = 0; i &amp;lt; anonids.length; i++) { &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;  &lt;span class="keyword"&gt;var&lt;/span&gt;&lt;span&gt; element = document.getAnonymousElementByAttribute(&lt;/span&gt;&lt;span class="keyword"&gt;this&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class="string"&gt;"anonid"&lt;/span&gt;&lt;span&gt;, anonids[i]); &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;  element.hidden = hidden; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="line"&gt;} &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
				&lt;/div&gt;
				&lt;p&gt;
				  To test this out, I went into my Firefox chrome directory (&lt;code&gt;C:\Program Files\Mozilla Firefox\chrome&lt;/code&gt; for me), 
				  unpacked &lt;code&gt;toolkit.jar&lt;/code&gt;, and made that change in &lt;code&gt;chrome\toolkit\content\global\bindings\tree.xml&lt;/code&gt;.  
				  &lt;a href="http://forums.mozillazine.org/viewtopic.php?t=318102"&gt;Console&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; let me know where to look.  In 
				  order to get Firefox to read my files, I had to edit &lt;code&gt;chrome\toolkit.manifest&lt;/code&gt; to look in the unpacked 
				  directory instead of the jar.
				&lt;/p&gt;
				Original toolkit reference:
				&lt;div class="CodeBlock"&gt;
				  content mozapps jar:toolkit.jar!/content/mozapps/ xpcnativewrappers=yes
				&lt;/div&gt;
				New toolkit reference:
				&lt;div class="CodeBlock"&gt;
				  content mozapps toolkit/content/mozapps/ xpcnativewrappers=yes
				&lt;/div&gt;
				&lt;p&gt;
				  Now that Firefox is looking at the unpacked source with the updated &lt;code&gt;tree.xml&lt;/code&gt;, I restarted Firefox and 
				  saw that it worked.  The next step was to file a bug, and submit a patch.
				&lt;/p&gt;
				&lt;p&gt;
				  As this was the first time I filed a bug at &lt;a href="https://bugzilla.mozilla.org/"&gt;Bugzilla&lt;/a&gt;, I did it wrong.
				  Asking
				  around on &lt;a href="irc://irc.mozilla.org/js"&gt;#js&lt;/a&gt;, Hannibal kindly told me to make a diff from CVS, and request a review.  I had to install 
				  &lt;a href="http://www.cygwin.com"&gt;cygwin&lt;/a&gt;, and 
				  partially followed &lt;a href="http://whereswalden.com/"&gt;Jeff&lt;/a&gt;'s instructions for 
				  &lt;a href="http://whereswalden.com/mozilla/msvcfree/"&gt;setting up an MSVC toolkit Firefox/Thunderbird build environment&lt;/a&gt;.
				  I wasn't concerned with needing to actually build it, so I only followed the bits about &lt;a href="http://www.cygwin.com"&gt;cygwin&lt;/a&gt;.
				  After getting a bash shell working, I followed the 
				  &lt;a href="http://developer.mozilla.org/en/docs/Mozilla_Source_Code_Via_CVS"&gt;Mozilla Source Code via CVS&lt;/a&gt; 
				  instructions, and got the source on my machine.  The build failed, but I didn't need it to build me anything, I just needed all
				  the source.
				&lt;/p&gt;
				&lt;p&gt;
				  Once I had the source, it was all very easy, following the 
				  &lt;a href="http://developer.mozilla.org/en/docs/Mozilla_Source_Code_Via_CVS"&gt;Mozilla Source Code via CVS&lt;/a&gt; verbatim.
				  After some browsing, I found a policy page for Toolkit patches, the 
				  &lt;a href="http://www.mozilla.org/projects/toolkit/review.html"&gt;Tookit Review Requirements&lt;/a&gt;.
				  From there I uploaded my patch to &lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=318036"&gt;my bug&lt;/a&gt;, and
				  requested review.  Within an hour or so, my request had been bumped to another toolkit dev, (the original guy is on vacation),
				  and  &lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=318036"&gt;my bug&lt;/a&gt;'s status had gone from UNCONFIRMED to NEW, and its looking to be put in the mozilla1.9alpha1 milestone.
				&lt;/p&gt;
				&lt;p&gt;
				  So, it looks like I might get a very trivial piece of code into Firefox, and have learned a lot more about how Mozilla's internals
				  work, and how open source development works.  If I get ambitious, I might get the source for other Mozilla projects and see 
				  if I can contribute to those.
				&lt;/p&gt;&lt;img src ="http://blogs.acceleration.net/ryan/aggbug/2805.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>
				  In the process of converting my remote XUL apps to use Firefox 1.5, I found a bug in <code>&lt;tree&gt;</code>.
				  The column picker breaks when you've added things to Array.prototype.  That took many hours to find, after removing and re-adding
				  countless lines of XUL and javascript.  It came down to some functions we were adding to Array.prototype in one of
				  our libraries.  When I commented those out, it worked just fine.  I installed the 
				  <a href="http://forums.mozillazine.org/viewtopic.php?t=318102">Console<sup>2</sup></a> extension, which gives some better
				  error reporting, and found the a javascript error occurring in a file called <code>tree.xml</code>.  It was a mess of XBL,
				  but the problem was apparent.
				</p>
				
				The orignal code:
				<div class="CodeBlock">

				  <table class="dp-c" border="0" cellpadding="0" cellspacing="0"><tbody><tr></tr><tr><td class="line"><span></span><span class="keyword">var</span><span> hidden = !tree.enableColumnDrag; </span></td></tr><tr><td class="line"><span class="keyword">const</span><span> anonids = [</span><span class="string">"menuseparator"</span><span>, </span><span class="string">"menuitem"</span><span>]; </span></td></tr><tr><td class="line"><span class="keyword">for</span><span> (</span><span class="keyword">var</span><span> anonid </span><span class="keyword">in</span><span> anonids) { </span></td></tr><tr><td class="line">  <span class="keyword">var</span><span> element = document.getAnonymousElementByAttribute(</span><span class="keyword">this</span><span>, </span><span class="string">"anonid"</span><span>, anonids[anonid]); </span></td></tr><tr><td class="line">  element.hidden = hidden; </td></tr><tr><td class="line">} </td></tr></tbody></table>
				</div>
				<p>
				  The problem is the usage of <code>in</code>.  <code>in</code> is rather introspective, and  will iterate over all 
				  the properties on the object, including user-added functions.  
				  My guess is the author of this code is used to the Python <code>in</code> keyword, which
				  just iterates over the values in the object.  I figure changing that to not use the in keyword should solve the problem:
				</p>
				<div class="CodeBlock">
				  <table class="dp-c" border="0" cellpadding="0" cellspacing="0"><tbody><tr></tr><tr><td class="line"><span></span><span class="keyword">var</span><span> hidden = !tree.enableColumnDrag; </span></td></tr><tr><td class="line"><span class="keyword">const</span><span> anonids = [</span><span class="string">"menuseparator"</span><span>, </span><span class="string">"menuitem"</span><span>]; </span></td></tr><tr><td class="line"><span class="keyword">for</span><span> (</span><span class="keyword">var</span><span> i = 0; i &lt; anonids.length; i++) { </span></td></tr><tr><td class="line">  <span class="keyword">var</span><span> element = document.getAnonymousElementByAttribute(</span><span class="keyword">this</span><span>, </span><span class="string">"anonid"</span><span>, anonids[i]); </span></td></tr><tr><td class="line">  element.hidden = hidden; </td></tr><tr><td class="line">} </td></tr></tbody></table>
				</div>
				<p>
				  To test this out, I went into my Firefox chrome directory (<code>C:\Program Files\Mozilla Firefox\chrome</code> for me), 
				  unpacked <code>toolkit.jar</code>, and made that change in <code>chrome\toolkit\content\global\bindings\tree.xml</code>.  
				  <a href="http://forums.mozillazine.org/viewtopic.php?t=318102">Console<sup>2</sup></a> let me know where to look.  In 
				  order to get Firefox to read my files, I had to edit <code>chrome\toolkit.manifest</code> to look in the unpacked 
				  directory instead of the jar.
				</p>
				Original toolkit reference:
				<div class="CodeBlock">
				  content mozapps jar:toolkit.jar!/content/mozapps/ xpcnativewrappers=yes
				</div>
				New toolkit reference:
				<div class="CodeBlock">
				  content mozapps toolkit/content/mozapps/ xpcnativewrappers=yes
				</div>
				<p>
				  Now that Firefox is looking at the unpacked source with the updated <code>tree.xml</code>, I restarted Firefox and 
				  saw that it worked.  The next step was to file a bug, and submit a patch.
				</p>
				<p>
				  As this was the first time I filed a bug at <a href="https://bugzilla.mozilla.org/">Bugzilla</a>, I did it wrong.
				  Asking
				  around on <a href="irc://irc.mozilla.org/js">#js</a>, Hannibal kindly told me to make a diff from CVS, and request a review.  I had to install 
				  <a href="http://www.cygwin.com">cygwin</a>, and 
				  partially followed <a href="http://whereswalden.com/">Jeff</a>'s instructions for 
				  <a href="http://whereswalden.com/mozilla/msvcfree/">setting up an MSVC toolkit Firefox/Thunderbird build environment</a>.
				  I wasn't concerned with needing to actually build it, so I only followed the bits about <a href="http://www.cygwin.com">cygwin</a>.
				  After getting a bash shell working, I followed the 
				  <a href="http://developer.mozilla.org/en/docs/Mozilla_Source_Code_Via_CVS">Mozilla Source Code via CVS</a> 
				  instructions, and got the source on my machine.  The build failed, but I didn't need it to build me anything, I just needed all
				  the source.
				</p>
				<p>
				  Once I had the source, it was all very easy, following the 
				  <a href="http://developer.mozilla.org/en/docs/Mozilla_Source_Code_Via_CVS">Mozilla Source Code via CVS</a> verbatim.
				  After some browsing, I found a policy page for Toolkit patches, the 
				  <a href="http://www.mozilla.org/projects/toolkit/review.html">Tookit Review Requirements</a>.
				  From there I uploaded my patch to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=318036">my bug</a>, and
				  requested review.  Within an hour or so, my request had been bumped to another toolkit dev, (the original guy is on vacation),
				  and  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=318036">my bug</a>'s status had gone from UNCONFIRMED to NEW, and its looking to be put in the mozilla1.9alpha1 milestone.
				</p>
				<p>
				  So, it looks like I might get a very trivial piece of code into Firefox, and have learned a lot more about how Mozilla's internals
				  work, and how open source development works.  If I get ambitious, I might get the source for other Mozilla projects and see 
				  if I can contribute to those.
				</p><img src ="http://blogs.acceleration.net/ryan/aggbug/2805.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Ryan</dc:creator><title>Server found request content type to be '', but expected 'text/xml'.</title><link>http://blogs.acceleration.net/ryan/archive/2005/11/10/2800.aspx</link><pubDate>Thu, 10 Nov 2005 17:43:00 GMT</pubDate><guid>http://blogs.acceleration.net/ryan/archive/2005/11/10/2800.aspx</guid><description>&lt;p&gt;I got this error when calling a C# web service from javascript.  With a message like that, you'd think
		there was a problem with the Content-Type on my HTTP request.
	 &lt;/p&gt;
	 &lt;p&gt;Using the fine &lt;a href="http://livehttpheaders.mozdev.org/"&gt;LiveHTTPHeaders&lt;/a&gt; 
		Firefox extension, I saw in the headers:
	 &lt;/p&gt;&lt;div&gt;Content-Type: text/xml; charset=UTF-8&lt;/div&gt;
	 Ok, so the content-type seemed ok, and it was time to start looking at my most recent changes to see where the bug was.
  
	 &lt;p&gt;
		After a bit of hunting, I found the problem.  My web service had an &lt;code&gt;int&lt;/code&gt; parameter, and I was passing in 't1245'.  That 
		caused a casting error, which .NET cleverly reported back as a problem with the content-type.&lt;/p&gt;
	 &lt;p&gt;Moral of the story: make your error messages meaningful.&lt;/p&gt;&lt;img src ="http://blogs.acceleration.net/ryan/aggbug/2800.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>I got this error when calling a C# web service from javascript.  With a message like that, you'd think
		there was a problem with the Content-Type on my HTTP request.
	 </p>
	 <p>Using the fine <a href="http://livehttpheaders.mozdev.org/">LiveHTTPHeaders</a> 
		Firefox extension, I saw in the headers:
	 </p><div>Content-Type: text/xml; charset=UTF-8</div>
	 Ok, so the content-type seemed ok, and it was time to start looking at my most recent changes to see where the bug was.
  
	 <p>
		After a bit of hunting, I found the problem.  My web service had an <code>int</code> parameter, and I was passing in 't1245'.  That 
		caused a casting error, which .NET cleverly reported back as a problem with the content-type.</p>
	 <p>Moral of the story: make your error messages meaningful.</p><img src ="http://blogs.acceleration.net/ryan/aggbug/2800.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Ryan</dc:creator><title>XmlSerializer eats default attributes</title><link>http://blogs.acceleration.net/ryan/archive/2005/10/17/2793.aspx</link><pubDate>Mon, 17 Oct 2005 16:06:00 GMT</pubDate><guid>http://blogs.acceleration.net/ryan/archive/2005/10/17/2793.aspx</guid><description>&lt;p&gt;
		So, I'm still working with XML generation, and I discovered an interesting design choice made by the writers of &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemxmlserializationxmlserializerclasstopic.asp"&gt;XmlSerializer&lt;/a&gt;.  
		My &lt;a href="http://blogs.acceleration.net/ryan/archive/2005/10/16/2792.aspx"&gt;efforts from yesterday&lt;/a&gt; were so I could use the XmlSerializer to generate
		flawless XML from C# objects, without going through the bother of string manipulation.  The XML it generates is well-formed, but it was leaving off an attribute ("Version"), and 
		I wasn't sure why.  I googled around and found another dev with the same problem.  &lt;a href="http://pluralsight.com/blogs/craig/"&gt;Craig Andera&lt;/a&gt;'s post 
		"&lt;a href="http://pluralsight.com/blogs/craig/archive/2004/07/27/1736.aspx"&gt;DefaultValue and XmlSerializer Don't Mix?&lt;/a&gt;" has a quick reproduction.
	 &lt;/p&gt;
	 &lt;p&gt;
		If you have an attribute with a default value defined in the DTD/XSD, and the C# variable representing that attribute has that value, then the 
		XmlSerializer chooses not to render the attribute.  Anyone reading the XML &lt;i&gt;must&lt;/i&gt; be using the same DTD/XSD, and they already know the default value, 
		so why waste bandwidth/space by rendering that attribute?  
	 &lt;/p&gt;
	 &lt;p&gt;
		Well, when the reader of my XML is using that missing "Version" attribute as a key for how it should process my XML, it makes a big difference.  Based on the 
		error message from the vendor, I think they are switching on that "Version" to pick a DTD, then validating against that and processing the request.
		It would be nice to have some kind of "RenderDefaultAttributesAnyway" flag I could set before serializing.  In the end I just changed the DTD to 
		remove the default value, and all was well.
	 &lt;/p&gt;&lt;img src ="http://blogs.acceleration.net/ryan/aggbug/2793.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>
		So, I'm still working with XML generation, and I discovered an interesting design choice made by the writers of <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemxmlserializationxmlserializerclasstopic.asp">XmlSerializer</a>.  
		My <a href="http://blogs.acceleration.net/ryan/archive/2005/10/16/2792.aspx">efforts from yesterday</a> were so I could use the XmlSerializer to generate
		flawless XML from C# objects, without going through the bother of string manipulation.  The XML it generates is well-formed, but it was leaving off an attribute ("Version"), and 
		I wasn't sure why.  I googled around and found another dev with the same problem.  <a href="http://pluralsight.com/blogs/craig/">Craig Andera</a>'s post 
		"<a href="http://pluralsight.com/blogs/craig/archive/2004/07/27/1736.aspx">DefaultValue and XmlSerializer Don't Mix?</a>" has a quick reproduction.
	 </p>
	 <p>
		If you have an attribute with a default value defined in the DTD/XSD, and the C# variable representing that attribute has that value, then the 
		XmlSerializer chooses not to render the attribute.  Anyone reading the XML <i>must</i> be using the same DTD/XSD, and they already know the default value, 
		so why waste bandwidth/space by rendering that attribute?  
	 </p>
	 <p>
		Well, when the reader of my XML is using that missing "Version" attribute as a key for how it should process my XML, it makes a big difference.  Based on the 
		error message from the vendor, I think they are switching on that "Version" to pick a DTD, then validating against that and processing the request.
		It would be nice to have some kind of "RenderDefaultAttributesAnyway" flag I could set before serializing.  In the end I just changed the DTD to 
		remove the default value, and all was well.
	 </p><img src ="http://blogs.acceleration.net/ryan/aggbug/2793.aspx" width = "1" height = "1" /></body></item></channel></rss>