关于在Sub里使用记录集的问题,遇到几次了,求解决办法?

NetBoy 2005-06-06 11:23:06
具体情况如下:

写了一个函数:
<%
Function SecVal(BoardID)
Dim rs_security,sqlstr_security

Set rs_security = Server.CreateObject("Adodb.Recordset")
sqlstr_security = "SELECT * FROM Net_User WHERE UserID="&CInt(UID)

rs_security.Open sqlstr_security,conn,3,3

If rs_security.Eof OR rs_security.Bof Then
RsClose
ConnClose
Response.Redirect "ShowError.asp?errid=0"
End If
Call CHKBalance(rs_security("UserGroupID"),rs_security("JoinDate"),rs_security("UserBalance"),rs_security("TotalTime"))

'关闭记录集,这里出了问题
RsClose
End Function
%>
<%
Sub CHKBalance(GroupID,JoinDate,Balance,TotalTime)
Dim UseDays
Select Case GroupID
Case 1
Case 2
Case 3
Case 4
Case 5
End Select
End Sub
%>
<%
Sub RsClose
rs_security.Close
Set rs_security = Nothing
End Sub

Sub ConnClose
conn.Close
Set conn = Nothing
End Sub
%>
...全文
131 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
小赵 2005-06-06
  • 打赏
  • 举报
回复
刚开始我也以为是
RsClose
ConnClose
Response.Redirect "ShowError.asp?errid=0"
这里关闭了RsClose
应该在后面加上 Response.end
可是看见下面各位的分析
我发觉更迷茫了1`
嘿嘿`1
NetBoy 2005-06-06
  • 打赏
  • 举报
回复
有点晕了,就是考虑到在函数SecVal中建立的记录集有作用范围,我需要用的记录集作为变量传递给Sub,但这样在函数SecVal中关闭记录集时仍然报错,晕了
zmhqyw 2005-06-06
  • 打赏
  • 举报
回复
我分析,因为你的记录集是在过程里定义的,所以有一个作用范围.

你调用专用的过程来访问记录集时,应该也是可以访问的.

而关闭的过程有点奇怪.

也许是这样.首先,判断出要执行close的这个记录集不是在当前的过程里定义的.然后就需要去找有没有同名的被定义的记录集.

问题出来了.

先去哪找呢? 如果是根据递归的倒序去找,那当然会想我们原本设想的一样,关闭调用本过程的上层过程里打开的记录集.

可是,我们知道,过程是可以嵌套和递归调用的.

而在每个过程执行的实例里,都有同名但作用范围不同的同名对象.

我举个简单例子.

sub foo(id)
dim rs
Set rs = Server.CreateObject("ADODB.Recordset")
sql = "select * from table where pid=" & id '这里是pid=id,类似一个树的遍历
rs.open sql ,conn,1,1
....
call foo(rs("id")) '在这里递归调用.
...
rs.close
end sub

在这个过程里,每次递归都会产生一个内容完全不同的rs.

这样看来,用一个过程去关闭某个rs就不太现实了......该关闭哪一个??

不知道.所以,只能是:都不关闭.

所以,就出现了上面的情况:找不到对象.

我没有尝试过同时在外面再定义一个rs的情况. 也许能把过程外的rs关闭也说不定.
有兴趣的兄弟可以试试.
showlin 2005-06-06
  • 打赏
  • 举报
回复
一般情况下,我都把诸如
Set rs_security = Server.CreateObject("Adodb.Recordset")
这样的recordset和connection对象放在程序最开头,而不是放在函数或者是过程内
而recordset也从不在中间set nothing,而只是调用close方法关闭
在程序的最后
set rs=nothing
set conn=nothing
zmhqyw 2005-06-06
  • 打赏
  • 举报
回复
Sub RsClose
rs_security.Close
Set rs_security = Nothing
End Sub

专门用一个过程来关闭记录集是完全没有必要的。我建议你直接用代码来关闭.

rs_securitey这样在过程里定义的记录集,按道理来说在其所有子过程里都是有效的并且可以访问的.

但是有时候,事情不能象我们想的那样发展..

我前些天异想天开,用函数做了一个数据库连接对象并返回一个引用

Function ConnectionDatabase()
Dim Conn
Set Conn = Server.CreateObject("ADODB.Connection")
Conn.open .....

ConnectionDatabase = Conn '这里返回了一个引用
End Function

Set ABC = ConnectionDatabase()

这样是可以访问这个abc的.

比如rs.open sql,ABC,1,1这样的语句可以执行.

但是ABC.Close会出错.而Set ABC = Nothing可以运行.这样,是释放了对数据库连接的引用.但是我们不知道数据库连接是否被关闭了.至于什么时候服务器真正的释放这条数据通道,我也无从得知.

这就违背了"及时释放"的原则.

所以,这样的代码在asp里是不可取的.

同样,你的语句里rs_...cloae不能执行,但是set nothing是可以的. 这样就不知道记录集是否被关闭了.

又因为你释放了引用,所以无从判断.

无奈.
NetBoy 2005-06-06
  • 打赏
  • 举报
回复
这里没有问题,问题在于:
我在函数SecVal里调用RsClose后,下面的CHKBalance就不能用了,报错如下:

-------------
技术信息(用于支持人员)

错误类型:
Microsoft VBScript 运行时错误 (0x800A01A8)
缺少对象: 'rs_security'
SecurityValidate.asp, 第 155 行

-------------
意思好像是说:记录集对像被关闭了

可是虽然CHKBalance写在后面,但调用是在调用RsClose之前啊
madpolice 2005-06-06
  • 打赏
  • 举报
回复
Response.Redirect "ShowError.asp?errid=0"

后面加上
Response.End
NetBoy 2005-06-06
  • 打赏
  • 举报
回复
照楼上所说,是不是存在这样的情况,
若记录不存在,是不是存在记录没有关闭记录集和数据库连接的情况下页面就跳转了

如果这个函数被大量调用,是不是违背了晚打开早关闭的原则。
dh20156 2005-06-06
  • 打赏
  • 举报
回复
If rs_security.Eof OR rs_security.Bof Then
RsClose
ConnClose
Response.Redirect "ShowError.asp?errid=0"
End If
Call CHKBalance(rs_security("UserGroupID"),rs_security("JoinDate"),rs_security("UserBalance"),rs_security("TotalTime"))

'关闭记录集,这里出了问题
RsClose

----------> 改一下:

If rs_security.Eof OR rs_security.Bof Then
Response.Redirect "ShowError.asp?errid=0"
Else
Call CHKBalance(rs_security("UserGroupID"),rs_security("JoinDate"),rs_security("UserBalance"),rs_security("TotalTime"))
End if
RsClose
ConnClose

28,391

社区成员

发帖
与我相关
我的任务
社区描述
ASP即Active Server Pages,是Microsoft公司开发的服务器端脚本环境。
社区管理员
  • ASP
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧