|
![]() |
名片设计 CorelDRAW Illustrator AuotoCAD Painter 其他软件 Photoshop Fireworks Flash |
|
本人在调试以下存储过程中碰到了很大的困扰(主要是临时表操作): CREATE PROCEDURE [c_readtop] @eachrow int=10 AS declare @tmpcat varchar(16) create table #tmp_result (arid int,cat2 varchar(16),title varchar(100),upday datetime) declare rt_cursor cursor for select cat2 from category where cat1=\\\'电脑手册\\\' and catl=2 open rt_cursor fetch from rt_cursor into @tmpcat while @@fetch_status=0 Begin set rowcount @eachrow Insert into #tmp_result (arid,cat2,title,upday) Select top 10 arid,cat2,title,upday from article as a left join category as b on a.sortid=b.catid where b.cat1=\\\'电脑手册\\\' and b.cat2=@tmpcat order by upday desc fetch from rt_cursor into @tmpcat End select * from #tmp_result drop table #tmp_result close rt_cursor deallocate rt_cursor 此存储过程的作用是取出每个分类的最新10条记录。 出现的错误信息是(一旦操作返回的记录集时就出现): ADODB.Recordset 错误 \\\'800a0e78\\\' The operation requested by the application is not allowed if the object is closed. 此存储过程能在qa中正常运行且能得到准确结果,使用odbc连接数据库的话,也能得到准确的结果。于是首先怀疑oledb方 式连接没能返回记录集。进行了下面的调试: (一)加调试标记,在调用记录集前用set rs=rs.nextrecordset测试是不是命中返回的记录集…… (二)由于该过存原来是另一个过程的一部分,怀疑存储过程中有些语句不能同时使用,于是将该过程分离成一个独立的 存储过程,错误依旧。 (三)怀疑调用该过程的Asp有问题,于是重做一个只是调用该存储过程的Asp程序,错误依旧。 (四)将连接方法改为odbc方法连接(建dsn,设sql server的login ID,设权限),该错误消失。重新使用oledb连接, 错误依旧。 (五)怀疑对临时表的数据插入有问题,取消去临时表插入数据,能返回一个空的记录集。 (六)经Bigeagle提示,将临时表建在临时数据库tempdb上,错误依旧 (七)把存储过程中的drop table去掉,在qa中运行该存储过程,观察临时表的生成情况,发现临时表准确生成且有准确 的数据插入,百思不得其解,数据输出到哪了? (八)经Bigeagle提示create table一句返回了记录集,于是重新在输出记录集前使用多个set rs=rs.nextrecordset(最 多放上了4个),错误提示依旧。 (九)怀疑临时表操作有问题,将临时表改为固定表,不插入数据时返回空记录集,插入记录时仍旧提示错误。在记录集 输出前先执行一个或多个set rs=rs.nextrecordset,终于有一次没有提示出错(检测到rs.eof为false),于是才恍然大 悟――不但是create table返回了记录集,而且连insert into语句也返回了记录集,不过该记录集得一种特殊的记录集 (没有字段,不能对该记录集进行任何操作――连检测rs.eof都不答应),我在此将它称为特别的记录集,方便下面引 用。 (十)知道了问题的症结,就立刻解决了,在存储过程中不希望返回记录集前执行set nocount on,要返回记录集时,先 执行set nocount off。 也就是改成: CREATE PROCEDURE [c_readtop] @eachrow int=10 AS declare @tmpcat varchar(16) set nocount on create table #tmp_result (arid int,cat2 varchar(16),title varchar(100),upday datetime) declare rt_cursor cursor for select cat2 from category where cat1=\\\'电脑手册\\\' and catl=2 open rt_cursor fetch from rt_cursor into @tmpcat while @@fetch_status=0 Begin set rowcount @eachrow Insert into #tmp_result (arid,cat2,title,upday) Select top 10 arid,cat2,title,upday from article as a left join category as b on a.sortid=b.catid where b.cat1=\\\'电脑手册\\\' and b.cat2=@tmpcat order by upday desc fetch from rt_cursor into @tmpcat End set nocount off select * from #tmp_result drop table #tmp_result close rt_cursor deallocate rt_cursor 问题解决。 在该存储过程调试过程中,发现oledb和odbc存在一个很大的差别,asp向odbc取记录集时,odbc过滤了上面所称的特 殊记录集(那种只占位置但不能进行任何操作的记录集――多由create table或insert into产生),而asp向oledb取记录 集时,oledb并没有将特别记录集过滤。 同时,熟悉到在使用存储过程返回记录集时,在不希望返回记录的地方,应该使用set nocount on禁止存储过程返回 记录集,否则可能会绕很多弯路。 终于明白了为什么绕了这么多弯路:没有想到oledb返回了这么多特别的记录集(还是由一个循环产生的,该循环执行 次数5、6次),怪不得在取记录集前虽然执行了set rs=rs.nextrecordset,但终因数据不够多而未能发现错误症结所在。 特殊感谢在调试过程中bigeagle给予的提示,多谢。 返回类别: 教程 上一教程: 网上“店铺”DIY(2) 下一教程: 用多种方式制作WEB页面的计数器 您可以阅读与"临时表操作的一些见解"相关的教程: · ASP获取数据库表名,字段名以及对字段的一些操作 · 对QUERY字段进行ENCODE操作的一点看法 · ASP中关于SESSION的一些问题 · FSO的一些特别功能 · 用不着妄自菲薄 对ASP和ASP程序员的一些话 |
![]() ![]() |
快精灵印艺坊 版权所有 |
首页![]() ![]() ![]() ![]() ![]() ![]() ![]() |