现在的位置: 首页 > 综合 > 正文

如何解决取ADO的Recordset对象的RecordCount属性总是-1

2013年08月07日 ⁄ 综合 ⁄ 共 7484字 ⁄ 字号 评论关闭

http://blog.sina.com.cn/s/blog_4bb9b26b010009bw.html

 

如何解决取ADO的Recordset对象的RecordCount属性总是-1?

 (2007-03-09 11:44:47)

  分类: ASP
如何解决取ADO的Recordset对象的RecordCount属性总是-1?

   最近在用asp做网页后台时,遇到了一个烦人的问题,RecordSet对象的RecordCount和PageCount均为-1.不能直接获取RecordCount属性,我就想了其他的笨办法代替,比如,利用了SQL的集函数select Count(*) as count from table,这样count中就存储了RecordSet的属性值;或者,利用一个变量存储,在游标从头到尾的搜索过程中,这个变量逐次加一,最终就得到了该属性:
<% dim i
i=0
set rs=conn.Open "select * from table"
do while not rs.EOF
i=i+1
rs.MoveNext
Loop
%>

   可是,接下来要用到PageCount属性来实现分页(AbsolutePage:指定当前页;PageCount:返回记录集中的逻辑页数;PageSize:指定一个逻辑页中的记录个数,缺省值是10.)这种方法行不通了,没办法,就开始到处搜集信息:
   首先让我们来看看怎么样获得记录集RecordSet,有以下几种:
<%
set conn = Server.CreateObject("ADODB.Connection")
set rs = conn.Open(sqlstring)
%>

另外一种方式:

<% set conn = Server.CreateObject("ADODB.Connection")
set cmd = Server.CreateObject("ADODB.Commend")
cmd.ActiveConnect = conn
cmd.StringText = "Select * from Table"
set rs = cmd.Open conn 
 %>

而另外一种办法就是:
<%
set rs = Server.CreateObject("ADODB.Recordset")
rs.open sql,conn,打开方式,锁类型
 %>

参数一表示游标类型,如下设置:
参数1              意    
只读,   数据只能向下移动
可读写,数据可以自由移动,多用户下别人不能看到新增数据(除非重启动)
可读写,数据可以自由移动,多用户下别人可以看到新增数据
只读 , 数据可以自由移动

参数2表示锁定类型,如下:
参数2           意    
默认值,   只读
                   悲观锁定
                   乐观锁定
                  批次乐观锁定
也就是说第一个参数为1或2的时候,才能有recordcount 

  所以也可以用recordset.open打开数据源:
   rs.CursorLocation = adUseClient
   rs.CursorType = adOpenStatic
   rs.open sqlstring,conn

   在我的程序中,改为第二种打开方式就可以正确访问RecordSet的那些属性了.具体就是:
rs.Open sqlstring,conn,1,3
   那么CursorLocation和CursorType到底是什么东西,能产生这么大的影响?
(1)CursorLocation:
设置或返回游标引擎的位置, 可设置为以下某个常量的长整型值:
adUseNone:   没有使用游标服务.(该常量已过时并且只为了向后兼容才出现)
adUseClient:
    使用由本地游标库提供的客户端游标。本地游标引擎通常允许使用的许多功能可能是驱动程序提供的游标无法使用的,因此使用该设置对于那些将要启用的功能是有好处的。adUseClientBatch 与 adUseClient 同义,也支持向后兼容性。
到这里大家应该明白为什么我们的游标会出问题及解决办法了.
adUseServer:
    默认值。使用数据提供者或驱动程序提供的游标。这些游标有时非常灵活,对于其他用户对数据源所作的更改具有额外的敏感性。但是,Microsoft Client Cursor Provider(如已断开关联的记录集)的某些功能无法由服务器端游标模拟,通过该设置将无法使用这些功能。
    注:当用于客户端(ADOR)RecordSet或Connection对象时,只能将CursorLocation属性设置为adUseClient.
(2)CursorType:
    指示在RecordSet对象中使用的游标类型,设置或返回以下某个CursorTypeEnum值:
adOpenForwardOnly(=0):
    仅向前游标,默认值.与静态游标相同,但只能在记录中向前滚动.当需要在记录集中单向移动时,可用于提高性能.
adOpenKeyset(=1):
    键集游标。尽管从您的记录集不能访问其他用户删除的记录,但除无法查看其他用户添加的记录外,键集游标与动态游标相似。仍然可以看见其他用户更改的数据。
adOpenDynamic(=2):
    动态游标。可以看见其他用户所作的添加、更改和删除。允许在记录集中进行所有类型的移动,但不包括提供者不支持的书签操作。
adOpenStatic(=3):
    静态游标。可以用来查找数据或生成报告的记录集合的静态副本。另外,对其他用户所作的添加、更改或删除不可见。
    注:如果将 CursorLocation 属性设置为 adUseClient,则只支持 adOpenStatic 的设置。如果设置了不支持的值,不会导致错误,并将使用最接近支持的 CursorType。
    当用于客户端 (ADOR) Recordset 对象时,只能将 CursorType 属性设置为 adOpenStatic。
   
   另外在查资料的过程中,发现网上也有好多人在问这个问题,看他们是怎么解决的,顺便汇总一下各方面的资料:
  
    打开方式有问题吧,后两个参数设为3,1试试,想更改用3,3,如果既要记录数又要允许修改就试1,3
rs.CursorLocation = adUseClient      '设为adUseClient
rs.Open  "sql语句",conn                         '或者游标类型为adOpenStatic
将返回记录总数

  当CursorType=1时,rs.RecordCount是不可用的,将其设为3即可。

  你只要将RecordSet的游标类型设置为客户端游标类型就行了:
  设置cursorlocation=adUseServer

 
  这个问题我碰到过,打开参数只有在为adopenstastic的情况下recordcont属性才能正确显示数据集中的记录值Recordset对象的游标类型会影响是否能够确定记录的数目。对仅向前游标,RecordCount性将返回-1,对静态或键集游标返回实际计数,对动态游标取决于数据源,返回-1或实际计数。
   RS.OPEN SQL,CONN,A,B    A为游标类型,B为锁类型
   A: adOpenForwardOnly(=0) 只读,且当前数据记录只能向下移动
      adOpenKeySet(=1) 只读,当前数据记录可自由移动
      adOpenDynamic(=2) 可读写,当前数据记录可自由移动
      adOpenStatic(=3) 可读写,当前数据记录可自由移动,可看到新增记录
   B: adLockReadOnly(=1) 缺省锁定类型,记录集是只读的,不能修改记录
      adLockPessimistic(=2) 悲观锁定,当修改记录时,数据提供者将尝试锁定记录以确保成功地编辑记录。只要编辑一开始,则立即锁住记录。
      adLockOptimistic(=3) 乐观锁定,直到用Update方法提交更新记录时才锁定记录。
      adLockBatchOptimistic(=4) 批量乐观锁定,允许修改多个记录,只有调用UpdateBatch方法后才锁定记录。 当不需要改动任何记录时,应该使用只读的记录集,这样提供者不用做任何检测。对于一般的使用,乐观的锁定可能是最好的选择,因为记录只被锁定一小段时间,数据在这段时间被更新。这减少了资源的使用。
     引用:

     记录集是否可写不是由光标类型决定的,而是由锁类型决定的。第一种光标(adOpenForwardOpnly)只能向前移动,第二种光标(adOpenStatic)可自由移动。但它们只决定了记录集是静态的,而不是“只读”的。而后面两种也不是“可读写”的,而是“动态”的。

    记录集分动态、静态两种,区别在于,记录集在打开的过程中,是否实时反映用户对数据库的更改(可能是当前访问数据集的用户,也可能是其他用户)。

    adOpenForwardOnly和adOpenStatic这两种属静态类型,当前用户打开记录集后,记录集就保持不变一直到关闭后再次打开它。在这过程中如果数据库中的相应记录发生改变,在当前用户是看不到的。

    adOpenDynamic和adOpenKeyset这两种则属动态类型,记录集会反映出数据库中相应记录的更改,他们两者的区别在于:adOpenDynamic是完全动态的,数据库记录的更新、删除、添加都会体现在当前用户所打开的记录集中;而adOpenKeyset则保持当前记录集的个数不变,它只体现更新操作,不体现删除和添加操作。

    另外,建议大家使用相应的ADO常量,而不是用一些让人摸不着头脑的数字。ADO常量非常有用,建议大家去记这些常量,而不是记数字。常量由英文单词组成,可以提高代码的可读性,更重要的是帮助我们理解常量所充当的作用。
   
    通常用于单纯显示的记录集,只需要用只向前、只读类型即可,而这两个属性是默认的,所以可以不设置,如:RS.Open strSQL, conn, adOpenForwardOnly, adLockReadOnly 等同于 RS.Open strSQL, Conn 打开这种记录集的执行效率是最高的!例外的是需要对记录集进行分页,这时必须替换adOpenForwardOnly为其它的,比如adOpenStatic就不错。而通常大家使用的rs.Open sql,
cn, 1, 1则需要更多的时间来打开,而应用中通常并不需要。

 ADO的RECORDSET的RECORDCOUNT属性总是为-1

    现象
    ====
    当在服务器端请求RecordCoun时会返回-1。这是因为ActiveX Data Objects (ADO) 2.0中的CursorType是adOpenForwardonly或者adOpenDynamic。如果是ADO 1.5,只发生在cursortype是adOpenForwardonly的时候。如果使用OLEDB provider for JET和SQL Server产生的结果可能不同,这依赖于数据库的提供者。
    提供者可能不支持某些CursorTypes。当你选择的CursorType不被支持时,提供者将选择最接近于你所请求的CursorType。请参考你的提供者的文档。此外,请注意不是所有的LockType和CursorType的组合都可以同时工作。改变LockType将强制改变CursorType。请确定使用调试来检查CursorType的值。
    
    原因
    =====
    
    在动态的游标中纪录号可能改变。Forward only的游标无法返回RecordCount。
    
    解决办法
    ==========
    使用adOpenKeyset(=1)或者adOpenStatic(=3)作为服务器端游标或者客户端游标。客户端只使用adOpenStatic作为CursorTypes,而不管你选择什么样的CursorType。
    
    状态
    ======
    
    这个形式是设计决定的。
    
    更多信息
    ================
    
    重复行为的步骤
    ---------------------------
    
    1. Open a standard .exe project in Visual Basic. From the Project menu, choose References. Select either the Microsoft Active Data Object 1.5 Library or the Microsoft Active Data Object 2.0 Library.
    
    2. Paste the following code in the form code window:
    
     Option Explicit
     Dim rs As ADODB.Recordset
    
     Private Sub Form_Load()
     'set up rs
     Set rs = New ADODB.Recordset
     rs.CursorLocation = adUseServer
     rs.Open "Select ProductID from products", & _
     "Provider=Microsoft.Jet.OLEDB.3.51;" & _
     "Data Source=d:\vb5_win95\nwind.mdb", _
     adOpenDynamic, adLockUnspecified
    
     Debug.Print rs.RecordCount
     End Sub
    
     3. Replace the preceding Data Source with a Data Source on your computer. Run the preceding form and note the record count. Change the CursorType to adOpenForwardonly and note the record count.
    
     4. Change the CursorLocation to adUseClient and experiment with the different CursorTypes. In all cases the correct record count returns.
   

    打开 Recordset 前设置 LockType 属性可指定打开时提供者应该使用的锁定类型。读取该属性可返回在打开的 Recordset 对象上正在使用的锁定类型。Recordset 关闭时 LockType 属性为读/写,打开时该属性为只读。

    提供者可能不支持所有的锁定类型。如果某提供者不支持所需的 LockType 设置,则将替换为其他类型的锁定。要确定 Recordset 对象可用的实际锁定功能,请通过 adUpdate 和 adUpdateBatch 使用 Supports 方法。

    如果 CursorLocation 属性被设置为 adUseClient,将不支持 adLockPessimistic 设置。设置不支持的值不会产生错误,因为此时将使用支持的最接近的 LockType 的值。

    远程数据服务用法   当在客户端 (ADOR) 的 Recordset 对象上使用时,LockType 属性只能设置为 adLockOptimisticBatch。

 rs.cursorlocation=3     '加上这一行
 rs.open   sql,conn,1,1

Recordset对象所有的属性和方法作者:
Recordset 属性 adOpenForwardOnly adOpenKeyset adOpenDynamic adOpenStatic
AbsolutePage     不支持 不支持 可读写 可读写
AbsolutePosition 不支持 不支持 可读写 可读写
ActiveConnection 可读写 可读写 可读写 可读写
BOF                只读 只读 只读 只读
Bookmark         不支持 不支持 可读写 可读写
CacheSize        可读写 可读写 可读写 可读写
CursorLocation   可读写 可读写 可读写 可读写
CursorType       可读写 可读写 可读写 可读写
EditMode           只读 只读 只读 只读
EOF                只读 只读 只读 只读
Filter           可读写 可读写 可读写 可读写
LockType         可读写 可读写 可读写 可读写
MarshalOptions   可读写 可读写 可读写 可读写
MaxRecords       可读写 可读写 可读写 可读写
PageCount        不支持 不支持 只读 只读
PageSize         可读写 可读写 可读写 可读写
RecordCount      不支持 不支持 只读 只读
Source           可读写 可读写 可读写 可读写
State            只读 只读 只读 只读
Status           只读 只读 只读 只读
AddNew           支持 支持 支持 支持
CancelBatch      支持 支持 支持 支持
CancelUpdate     支持 支持 支持 支持
CancelUpdate     支持 支持 支持 支持
Close            支持 支持 支持 支持
Delete           支持 支持 支持 支持
GetRows          支持 支持 支持 支持
Move             不支持 支持 支持 支持
MoveFirst        支持 支持 支持 支持
MoveLast         不支持 支持 支持 支持
MoveNext          支持 支持 支持 支持
MovePrevious     不支持 支持 支持 支持
NextRecordset    支持 支持 支持 支持
Open      

抱歉!评论已关闭.