如何最有效的使用ADODB.RecordSet?

SunWinter 2003-01-28 03:57:41
我们都知道ADODB。RecordSet有以下两种写法
dim recTemp as adodb.recordeset
set recTemp = new adodb.recoordset

dim recTemp as new adodb.recordest

'为此,我做了如下的测试程序

Option Explicit

Private AdoRs1 As ADODB.Recordset
Private AdoRs2 As New ADODB.Recordset

Private Sub CmdTest_Click()
'Step1: 新建一个ADODB.RecordSet实例; 注意 AdoRs2不需要新建

Set AdoRs1 = New ADODB.Recordset

'Step2: 执行某些操作
MsgBox "AdoRs1字段个数 :" & AdoRs1.Fields.Count
MsgBox "AdoRs2字段个数 :" & AdoRs2.Fields.Count

'Step3: 释放RecordSet
If AdoRs1.State = adStateOpen Then
AdoRs1.Close
End If
Set AdoRs1 = Nothing

If AdoRs2.State = adStateOpen Then
AdoRs2.Close
End If
Set AdoRs2 = Nothing

'Step4: 测试被释放后的RecordSet (注意测试的顺序)
If AdoRs1 Is Nothing Then
MsgBox "AdoRs1 被完全释放 !"
Else
MsgBox "AdoRs1 没有被完全释放 !"
End If

If AdoRs2 Is Nothing Then
MsgBox "AdoRs2 被完全释放 !"
Else
MsgBox "AdoRs2 没有被完全释放 !"
End If

MsgBox "AdoRs2字段个数 :" & AdoRs2.Fields.Count
MsgBox "AdoRs1字段个数 :" & AdoRs1.Fields.Count

End Sub

'经过以上测试后, 我们发现一个有趣的现象:
'AdoRs1被释放后不能读取AdoRs1的某些属性 , 必须重新执行
'Set AdoRs1 = New ADODB.Recordset 方可使用某些属性
'这样可能造成某些不方便

'AdoRs2被释放后仍然能读取AdoRs2的某些属性
'这样是否会造成资源没有被完全释放,造成对程序运行效率的影响

'希望大家能对该问题进行一些讨论和指教,谢谢。

...全文
391 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
SunWinter 2003-01-30
  • 打赏
  • 举报
回复
我认为,第一种写法也许更规范一些,但使用以来比较麻烦,特别是对于全局的ADODB.RecordSet或全局的ADODB.Connection.(有时候是需要用到这些全局变量的),例如
Global gAdoCnn as ADODB.Connection

因为每次使用以上全局变量时,都需要执行判断语句:
if Not gAdoCnn is Nothing then
'...
endif

但是,如果我们将变量写成以下形式,
Global gAdoCnn as New ADODB.Connection
则每次使用时,都不需要执行 if Not gAdoCnn is Nothing then 语句。

另外,如果ADODB.RecordSet是局部变量,则讨论对象的资源是否被释放好象意义不大,不知各位意见如何?







sanil 2003-01-29
  • 打赏
  • 举报
回复
标准的是第一种更为规范,无论是在微软出版的书籍和参考资料来看,都是先声明,然后在用的时候实例化,用完后关闭。这不仅是在STUDIO6中在STUDIO.NET中尤其是这样。
xystarch 2003-01-29
  • 打赏
  • 举报
回复
set object=nothing 和com 接口的 release() 很像,它会测试该object的引用计数,当没有其他的引用与该对象相关联的时候,就会释放这个对象的资源,如果仍然有引用存在,set object=nothing 并不能释放该object的资源。而是使得对象引用计数减1。
因此,你的这个测试表明有一个隐式的引用存在。
但是对于 AdoRs2来说,set nothing 却将它的属性重新初始化了?!
谁知道vb.dll是怎么处理 set nothing 这条语句的。也不知道vb是怎么在调用ADO的COM接口。或许你将几个vb.dll反汇编掉就会弄明白是怎么回事情了。

至于性能,使用由 New 关键字声明的变量会减慢应用程序的运行速度。因为 Visual Basic 每次遇到用 New 声明的变量时,都要测试是否已将对象引用赋给该变量。所以,最好不要用 dim ...as New...的声名方法了.

By the way,参考MSDN 或许对你有帮助。你的测试程序还可以改进很多!
SunWinter 2003-01-29
  • 打赏
  • 举报
回复
To xystarch(xjj):
谢谢你的指点。可能是我的意思没有表达清楚,我现在改写了测试程序。请大家将下列程序拷贝到一个Form中,运行一下。
我的疑惑就是,为什么对ADODB.RecordSet声明的两种不同写法,效果却不一样,哪一种更规范,更有效。

Private Sub Command1_Click()
'这是一个测试程序
Dim AdoRs1 As ADODB.Recordset
Dim AdoRs2 As New ADODB.Recordset

On Error GoTo ErrTest

'Step1: 新建一个ADODB.RecordSet实例; 注意 AdoRs2不需要新建

Set AdoRs1 = New ADODB.Recordset

'Step2: 执行某些操作
MsgBox "AdoRs1字段个数 :" & AdoRs1.Fields.Count
MsgBox "AdoRs2字段个数 :" & AdoRs2.Fields.Count

'Step3: 释放RecordSet
If AdoRs1.State = adStateOpen Then
AdoRs1.Close
End If
Set AdoRs1 = Nothing

If AdoRs2.State = adStateOpen Then
AdoRs2.Close
End If
Set AdoRs2 = Nothing

'Step4: 测试被释放后的RecordSet (注意测试的顺序)
If AdoRs1 Is Nothing Then
MsgBox "AdoRs1 被完全释放 !"
Else
MsgBox "AdoRs1 没有被完全释放 !"
End If

If AdoRs2 Is Nothing Then
MsgBox "AdoRs2 被完全释放 !"
Else
MsgBox "AdoRs2 没有被完全释放 !"
End If

MsgBox "AdoRs2字段个数 :" & AdoRs2.Fields.Count
MsgBox "AdoRs1字段个数 :" & AdoRs1.Fields.Count

Exit Sub

ErrTest:
MsgBox "获取AdoRs字段个数不成功, 请检查AdoRs1对象是否有效 !"
End Sub
xystarch 2003-01-28
  • 打赏
  • 举报
回复
当然,按照规范来设计程序,是一点问题也没有的。
xystarch 2003-01-28
  • 打赏
  • 举报
回复
这没什么好奇怪的!不过用VB做开发的人有这样的疑问也很正常。
楼主去看看COM本质论之类的书就会明白的

这其实是一个对象生命周期的问题。
ADO.Recordset对象在FORM级 new一个以后实际上建立了全局对象
调用了类厂的AddRef(),将此对象与Form容器相关联,Recordset不能单独存在,它依靠connection实际上也使得connection对象引用计数。
按照规范,全局对象的释放必须在它的容器的析构函数中进行,而不是在局部过程中进行。

也可以换句话说,在VB中,有些东西你控制不了,VB掩盖了太多的细节和底层
SunWinter 2003-01-28
  • 打赏
  • 举报
回复
Private AdoRs1 As ADODB.Recordset
Private AdoRs2 As New ADODB.Recordset
以上是Form级的变量。

以上程序在每一台机器上测试结果一定是相同的。有兴趣者可把以上程序拷贝到一个新的Form中,并在Form中增加一个按钮 CmdTest即可
CoolAbu 2003-01-28
  • 打赏
  • 举报
回复
我觉得你的这个测试挺有意思的,也许每个机子上测试的结果都不是太相同
CoolAbu 2003-01-28
  • 打赏
  • 举报
回复
Nod...

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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