rs.CursorLocation = adUseClient
rs.Open "select * from tt", cn, adOpenStatic, adLockOptimistic
for i=1 to rs.recount
    rs.Fields("序号") = i
      rs.Update
      rs.MoveNext
next i
但是每次只能修改其中部分数据,大概能修改几千个吧!不能完全修改,而且程序还出现不相应!然后我修改的循环为下面的:试试看看能不能全部修改!但是还是不行,出现一样的情况!
Do While rs.EOF = False
      rs.Fields("序号") = i
      rs.Update
      rs.MoveNext
Loop最后我修改rs.CursorLocation =aduseserver
这样才能正常运行!天啊!我个刚刚给单位做了一个程序,都是使用的aduseclient,天那后果不能想象啊!
所以请各位高手帮兄弟一把了!
为什么出现这种情况!使用rs.CursorLocation =aduseclient怎么能解决上面出现的情况!
万分感谢

解决方案 »

  1.   

    rs.CursorLocation = adUseClient
    rs.Open "select * from tt", cn, adOpenStatic, adLockOptimisticif rs.recount > 0 then
       rs.movelast
       rs.movefirst
    end iffor i=1 to rs.recount
        rs.Fields("序号") = i
          rs.Update
          rs.MoveNext
    next i
      

  2.   

    楼上的,感谢你的帮忙
    但是这段代码代表什么意思?起什么作用?难道没有这段代码就不可以吗?
    if rs.recount > 0 then
       rs.movelast
       rs.movefirst
    end if
    你的方法和我的方法可以读取全部数据?为什么我的方法只能修改部分数据呢?请你说清楚点可以吗!
      

  3.   

    哈哈  你惨了 哈哈...  我不知道那个作用是什么 但我每次用SQL 时都声明一下这样才不会出错 
    ^_^  有问题了你在去给升级被. ..钱都拿了 还怕啥 ..只要不能毁坏他们的数据就行
      

  4.   

    记录指针要先移动到第一条记录。
    rs.CursorLocation = adUseClient
    rs.Open "select * from tt", cn, adOpenStatic, adLockOptimistic
    rs.movefirst
    for i=1 to rs.recount
        rs.Fields("序号") = i
          rs.Update
          rs.MoveNext
    next ifor i=1 to rs.recount
        rs.Fields("序号") = i
          rs.Update
          rs.MoveNext
    next i
      

  5.   

    楼上的谢谢了!
    rs.movefirst
    for i=1 to rs.recount
        rs.Fields("序号") = i
          rs.Update
          rs.MoveNext
    next i
    这个方法我也试过了也不行!
    各位高手请你们自己也在一个有10000条以上的表里实验一下!
    这样的小问题都不能解决,还做什么程序!
    都亲自实验看看让我们讨论一下!
      

  6.   

    当表里记录很多时,客户端的记录集是不会全部把它们读进来的,所以这时候取的记录总数并不是真实的全部记录数,但你强制移动到尾巴再移回来后,就能得到真实的记录总数了。所以这也解释了客户游标和服务器游标的问题了。明白了吧。
    另外你最好批量更新,不要一条条UPDATE,效率高许多。
      

  7.   

    应该就是记录数的问题,用上面几位的方法应该能行的通
    ------------------------------------------------------------
    楼上的谢谢了!
    rs.movefirst
    for i=1 to rs.recount
        rs.Fields("序号") = i
          rs.Update
          rs.MoveNext
    next i
    这个方法我也试过了也不行!
    各位高手请你们自己也在一个有10000条以上的表里实验一下!
    这样的小问题都不能解决,还做什么程序!
    都亲自实验看看让我们讨论一下!
    -----------------------------------
    上面第一句应该是movelast
      

  8.   

    用批量提交或事务,绝对没有问题,我测试过数据10000 条,代码如下
    Dim Cn As New ADODB.Connection
    Dim Rs As New ADODB.Recordset
    Dim II As Long
    Cn.Open "Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initial Catalog=test1;Data Source=super"
    Rs.CursorLocation = adUseClient
    Rs.Open "select * from test", Cn, adOpenStatic, adLockBatchOptimisticIf Rs.EOF = False Then
        Rs.MoveLast
        Rs.MoveFirst
    End If
    For II = 1 To Rs.RecordCount
        
        Rs(0) = II + 1
        Rs.Update
        Rs.MoveNext
        
    Me.Caption = II
    DoEvents
    NextRs.UpdateBatch adAffectAllChaptersRs.Close
    Cn.Close
      

  9.   

    楼上的各位兄弟谢谢你们了,我涨了不少知识!
    当表里记录很多时,客户端的记录集是不会全部把它们读进来的,所以这时候取的记录总数并不是真实的全部记录数,但你强制移动到尾巴再移回来后,就能得到真实的记录总数了。所以这也解释了客户游标和服务器游标的问题了。明白了吧。
    __________________________________________
    我试验了一下!在没有强制移动记录指针的情况下,使用客户端记录集,首先使用rs.recordcount所给出的记录数是正确无误的,无论试验多少次!其次使用数据网格进行数据显示也能够完全显示,并且使用rs.movenext也能够全部遍历数据表里的所有数据!
    那这不是和不会全部读进数据表相冲突码?
    楼上的我不是否认你的方法,而我只是不明白,为什么会出现这样的区别!所以还请你们多指教了!
    让我完全明白!谢谢各位了!
      

  10.   

    那么会发生运行时错误,至于是否全部被取消不明确,你最好对它使用事务,以便错误时回滚。
    下面我也抄一下书(微软的)
    如果 Recordset 对象支持近似定位或书签(即 Supports (adApproxPosition) 或 Supports (adBook) 各自返回 True),不管是否完全填充该值,该值将为 Recordset 中记录的精确数目。如果 Recordset 对象不支持近似定位,该属性可能由于必须对所有记录进行检索和计数以返回精确 RecordCount 值而严重消耗资源。
    Recordset 对象的游标类型会影响是否能够确定记录的数目。对仅向前游标,RecordCount 属性将返回 -1,对静态或键集游标返回实际计数,对动态游标取决于数据源返回 -1 或实际计数。
    抄书完毕。对大量记录的表人为移动指针到尾巴再回来以取得记录数不但效率高,而且能保证数据的准确性。
    至于说MOVENEXT循环下来也能获得全部记录的数据,那是一定的,当它发现缓冲里没有数据之后肯定就继续向库里要数据的,至于细节大概只有数据库开发者知道了。
    你使用EOF来作为循环的结束条件是正确的,而使用记录总数就比较冒险,停止响应的原因不是记录总数的问题,而是频繁UPDATE的缘故(排除法)吧。
      

  11.   

    province_(雍昊) 以及所有楼上的兄弟谢谢你们了!帮了我很大的忙!有沈阳的说声,一定请客!如果我想得到rs.recordcount是不是最好先做rs.movelast、rs.movefirst,这样所得到的recordcount的值是十分精确的?
    还有我的程序使用了Rs.Update、Rs.MoveNext,这样按照理论我应该能读出所有记录并进行全部修改!
    而实际上没有进行全部修改的,原因是不是因为频繁使用update使程序无响应,中途停止工作,从而导致了部分数据没有被修改!因为我以前从来没有遇到过这种情况所以实在是不太明白!
    还有请教一点一般情况下使用aduseserver和aduseclinet哪一个好!还有游标类型使用哪一个好?最后一个问题了!请大家多帮忙!感激不尽!
      

  12.   

    还有你们引用的是ado哪个版本?我引用的是2.0
      

  13.   

    province_(雍昊)兄弟你帮了我很多忙谢谢了!还有两个问题已经在上面了请你多给点意见!
      

  14.   

    doevents有什么作用以前只是见过没有用过所以不清楚!
    我现在就是对一些原理不是很清楚(因为经验太少,没有遇到过太多的问题!)楼上的紧接着你的回帖上面提了两个问题请给点具体建议!
    Dim cn As New Connection
    Dim rs As New Recordset
    cn.CursorLocation = adUseClient
    rs.CursorLocation = adUseClient
    记录集打开的时候是不是还是以rs的为标准?
      

  15.   

    DOEVENTS只是为了使窗口对用户操作(主要就是MOUSE和键盘)及时反应,如果你知道自己的程序运算量大,费时多,不用它也可以,效率高么。
    停止反应的原因我也只是推测是频繁UPDATE的缘故,当然可能性是很大的。每次UPDATE的时候,数据库系统就要把缓存里的数据写到库中,如果表里有索引和字段规则,系统还要再去检查。平时少量的UPDATE可能觉察不出来,但象你上万次连续调用会使系统的性能变得很差,如果是企业级数据库系统就要好一些,但使用记录集来修改数据库本来也不是什么高效的办法。我一般万不得已的时候用一下吧。(比如向IMAGE字段插入图片等)一般情况下最好使用SQL来操作,其中好处很多,其中之一是便于记载操作动作,特别是需要把本地数据库的更新反映到远地库时特别有用。
    写这些并不表示我对你说的停止反应有明确的原因判断,只是基于自己的经验而已,如果你有新发现,也请以后帖出来,大家一起学习一起进步吧。另外关于游标我再抄下书:
    关系数据库中的操作会对整个行集产生影响。由 SELECT 语句返回的行集包括所有满足该语句 WHERE 子句中条件的行。由语句所返回的这一完整的行集被称为结果集。应用程序,特别是交互式联机应用程序,并不总能将整个结果集作为一个单元来有效地处理。这些应用程序需要一种机制以便每次处理一行或一部分行。游标就是提供这种机制的结果集扩展。 
    游标通过以下方式扩展结果处理: 
    允许定位在结果集的特定行。
    从结果集的当前位置检索一行或多行。
    支持对结果集中当前位置的行进行数据修改。
    为由其他用户对显示在结果集中的数据库数据所做的更改提供不同级别的可见性支持。Using Server Cursors with ADO
    ADO and OLE DB map cursors over the result sets of executed SQL statements. SQLOLEDB implements these operations using server cursors, which are cursors implemented on the server and managed by API cursor functions.Server Cursor Details
    To use a server cursor, an application can set these properties to anything other than the default value: Set the cursor type of the Recordset object to adOpenKeyset, adOpenDynamic, or adOpenStatic.
    Set the LockType of the Recordset object to adLockPessimistic, adLockOptimistic, or adLockBatchOptimistic.
    Set the CacheSize property to anything other than the default value of 1. 
    The CursorLocation property should remain at the default setting, adUseServer.Server cursors are created only for statements that begin with: SELECT
    EXEC[ute] procedure_name
    call procedure_name 
    Even if an application explicitly requests a server cursor, server cursors are not created for statements such as INSERT.Server cursors cannot be used with statements that generate more than one recordset. 
      

  16.   

    province_(雍昊) ( )非常感谢你!帮我解决了很多问题!你要是在沈阳,或者来沈阳旅游一定请你!更具你的帮助,还有我自己理解反复做了很多遍的试验,发现我开始最根本的错误就是你说的总是update所以造成了资源的大量占用!所以出现无响应!如果耐心的等待(最少要10分钟吧)程序正常运行,并提示完成修改(提示是我自己做的).得出结果就是因为无响应,而手动结束程序,造成部分数据被修改!所以我的问题已经彻底解决问题了!非常感谢你!下面呢所以问题中出来的问题了!非常希望能和你讨论!
    1,使用客户端打开数据表,而没有使用movelast,movefirst的情况下recordcount的返回结果是否正确无误?根据我的经验,应该是正确无误的!不知道你怎么看?2,你说用sql进行记录,不知道你有没有特指?是指存储过程还是update,insert?如果是存储过程?刚学的时候认为太复杂就没有看了(打算以后看,我手里的书介绍的也简单);如果是update,insert我认为在vb里写的话没有用ado写的直观,易懂。还有就是如果想用文本控件的值对数据表进行修改,使用sql的话我认为必须要先赋值给变量,再在sql语句里调用这个变量?我感觉是很麻烦?不知道你使用什么方法,也不知道我说的对不对!请指点!3,关于事务.我手里的资料介绍说:access数据库具备事务处理能力,在使用客户端游标的情况下,就不能使用事务处理了,这意味这单机上使用access文件的功能就不能进行事务处理。我使用sql server 2000在单机下、无论使用客户端游标,还是服务端游标都能进行事务处理。这是不是说明sql server本身就是一个数据库服务器,而access文件只是文本而缺少服务器的支持造成的?打算我的开发程序使用以后,总一下vb+sql server 2000的经验,发个帖,和大家一起讨论,到时请多多支持了!再次谢谢你!
      

  17.   

    个人认为用do while not eof好,不要用for循环,原因就是数据多的时候读不全
      

  18.   

    哈哈,这么客气,沈阳(辽宁省)估计难得去,太远了(我浙江台州的)。不过辽宁倒有同学,可惜联系中断接不上头了。
    问题一、可能我们实验的表记录较有限吧,既然微软文档(我上面好象抄过,咦,那一段E文的哪去了?)里说过记录集不会一次性把所有数据都弄进来,而且RECORDCOUNT也有可能是近似值,那就这么记着吧,反正也不多两行代码。是吧。事实上我做过的应用由于记录数都比较有限最多不上万,所以也不是很拘泥于这一点。(又是个说归说做归做的家伙^_^)
    问题二、我是有所特指的,(说来也是个教训,后果很严重,MONEY损失很大啊,不展开来了。),比如一个系统,客户端要求速度快,因为业务忙,所以不能连到远程数据库(因为是ADSL上网),当天的业务全部是在本地ACCESS里做,结束时就涉及到更新INTERNET上的库了,怎么办?可以把本地库的操作记录用文本存下来,批处理时就用它来更新总库。如果你是用记录集,那就麻烦大了。(我居然把这种东西都帖出来了,你的客请定了^_^)
    问题3、回滚的支持取决于数据引擎,ADO2。1对ACCESS同样支持,而且那个游标在缺省时都是服务器游标的。SQL 2000在默认时回滚是默认打开的(好象是的,不过我一般还是显式使用事务,保险么)。
    我的经验里这个游标还是别去管,就取系统默认的。
    好了,兄弟可以结帖了,有机会再聊吧。SEE YOU。
      

  19.   

    谢谢大家的支持尤其是province_(雍昊) ,一定放分!