This is a nasty error. It's an assertion (SQL Server Assertion: File:
, line=1378
Failed Assertion = 'm_offBeginVar < m_SizeRec'.). If you do a search on Google, it looks like it's a really odd data corruption problem.
So I took the query in question (a really long, drawn out select statement from a web page. Don't ask me why it wasn't in a stored proc) and ran it in Query Analyzer. QA ran the query fine. Same results as what the web page should have displayed. If this was genuinely a data corruption problem, I'd expect the query to blow up in QA as well as from IIS. Hmm. A mystery.
I fired up Profiler. Love the profiler. Remember SQLEYE we had during the 4.21 days. Ah, nostalgia. As a sidebar, SQLEYE used to let the administrator "hijack" particular spids inject error messages back to the user. So we always used to send high-severity messages of "you suck" to each other. Real mature. At any rate, SQL Profiler didn't show the query coming in from the web server. OK, this is getting really strange.
I had a developer look at the web page. He saw some questionable things (above and beyond the fact that the page was sending dynamic SQL instead of stored procs) on the page. The page opened the connection, used a recordset (which worked fine) and then without closing the recordset it reopened the recordset with a new query (the one that bombed). The developer dropped in a set rs=Nothing on the webpage, and the problem magically went away.
My theory on what was happening was that the actual error wasn't a data corruption problem in the database, but a data corruption problem in the bit of memory that SQL Server uses to store inbound queries, probably because the query text was corrupt. I think the query text was corrupt because when the second query was executed the memory object on the IIS server that handled the query wasn't reset properly before it was reused.
Bear in mind that SQL Server does ALL memory allocation in pages and extents, even the bits that are actually network code, so if you somehow put corrupt data into a query you can crash the connection. An excellent DOS attack against the server, because the server has to do a memory dump and it closes the actual connection, so if you dump a few thousand of those to the server in a short period of time, you'll bog the server down pretty bad.
The moral of the story? Don't reuse recordsets that way. Do everything in stored procs. And, of course, don't allow non-trusted access to your sql server's network ports.