..解压,转为一个记录集...这是什么记录集,是用什么格式存储的,可转化成ClientDataSet吗?

解决方案 »

  1.   

    我建议你建立两个TADOConnection,一个连接SQL Server,另外一个连接Access 2000。我想你要导入数据肯定是表结构是相同的,那么你可以直接用两个Dataset做SQL查询
     Insert into Accesstable select * from SQLTable
    我想SQL的导入工具远离也是这样的,你是先把SQL上的表格取过来,在本地存放成文件,还要压缩解压,然后再放到数据集,再导入到Access,这样走了很多弯路,当然会很费时间,为什么不直接在两个数据源之间导入呢?这样一定会很快的,至于实现过程,我想对你来说应该是很简单了吧。
      

  2.   

    笑三少,就是普通的Recordset啊。
      

  3.   

    debussy,两个connection是在不同机器上,机器之间是慢速链路,拨号连接的,
    光读个一万条记录出来我看过,记录集的大小大概是5-600k,如果不压缩就传,
    基本上是一分多钟,客户不接受。另外,我现在的实现方式就是为了节省服务器资源,提高效率,全部都在内存中
    操作,读了SQL后我把内存流直接压缩就传走了。
      

  4.   

    如果能转化成ClientDataSet,就有方法处理了
      

  5.   

    你可以使用一些第三方控件集(如EMS QuickExport)将"转化到本地的记录集"输出为一个Excel,DBF等,再使用SQL查询!
      

  6.   

    你把问题说得复杂化了,依我的理解:(下面引用原话)问题很简单,远程机器上是Sql Server 2000,本地机器上是Access 2000,现在已经完成的部分是:远程机器上读取一个表的数据,转为流,压缩,通过Socket传送到本地,解压,转为一个记录集,现在使用类似DBGrid的感知控件可以读出其中数据,但用户要求对这个数据集进行查询,我不会对数据集使用SQL,准备存储到Access 2000中再处理。现在的问题是存储过程非常慢,5000-10000条数据大概要两分钟,而使用Access 2000的数据导入功能只需要一秒附近。也就是说解压后的数据如何在短时间内导入Access, 即本地数据导入本地Access
    数据库!只要不是单条循环处理就肯定不用2分钟,最简单的办法,用BatchMove好了,5000-10000条记录最多只要几秒。
      

  7.   

    你用我的代码试试:
    我的赛杨333录入4600条记录用了6秒钟.
    做了一个通用的程序:
    http://netroom.hbu.edu.cn/personal/mudeen/quickcopy.exe
    源码如下:
    http://netroom.hbu.edu.cn/personal/mudeen/quickcopy.zip
    关键代码如下:
    if fileexists('c:\12.dat')  then
    begin
     
    adodataset2.LoadFromFile('c:\12.dat');
    end
    else
    exception.Create('尚无本地数据包,请重新下载远程数据库');
    // button3.Enabled:=gotdata;
     adoquery1.Connection:=adoconnection2;
     adoquery1.Close;
    with adoquery1 do
        begin
         locktype:=ltBatchOptimistic;
         sql.Clear;
         sql.Add(adodataset1.CommandText+' where 0=1');
        // showmessage(sql.Text);
         open;
         end;
            begin
        application.ProcessMessages;
        adodataset2.DisableControls;
         while not adodataset2.eof do
         begin
         adoquery1.Insert;
         for i:=0 to adodataset2.FieldCount-1 do
          adoquery1.Fields.Fields[i].Value:=adodataset2.Fields.Fields[i].Value ;
          adodataset2.Next;
         end;
         adodataset2.First;     edit2.Text:=datetimetostr(time);
         adodataset2.EnableControls;
         adoquery1.UpdateBatch(arall);     end;
      

  8.   

    johnson,实在没有办法我也只能用batchmove了,当时不考虑这个的原因是第一batchmove作我的数据导入也不是几秒钟就能完成的,第二要求客户端又要安装BDE,我的客户分布得很广,绝大多数都是在城市近郊,55555555,要发布或者更新一次软件非常困难,客户素质又极低,不可能要求他们自己做。所以我这里的问题其实就是希望能得到代码调用SQL Server 2000的导出过程和Access 2000得导入过程,并不是说没有方案解决。正如你所说,如果按照单条录入的话,效率怎么都不可能高,那么就没有人考虑过为什么Access或SQL Server得导入导出效率为
    什么这么高,我们是否可以利用呢?这些天我最大感触是项目和学习是不一样的,
    学习的时候也许只要有解决方案就可以,而项目更多要考虑效率等其他一些客观问题。
      

  9.   

    笑哥哥,你的代码我要测试一下看看,不过够呛,我以前的代码跟你的差不多,逐条的话确实效率不高,你的Field可能不多,数据也简单,我的9个Field,做起来很慢
      

  10.   

    ADO撒,都是OLEDB连接,一句SQL不就完了
      

  11.   

    vbFly你说什么效率接近DTS?batchmove?那绝对不是,可以马上做实验,数据越多越能看出差别,至少我用一万条数据就已经明显看出太大的差别了。
      

  12.   

    还有你说用ADO,我的机器间是慢速连接,客户数量不小,不是那么简单。
      

  13.   

    icewolf:我觉得我的代码问题不大.因为是在内存中操作,我昨晚试验的数据库表的结构如下:
    au_id au_lname au_fname phone address city state zip contract
    刚好也是9个field.而且我是在333中测试的,如果机器配置好速度应该更快.
      

  14.   

    debussy(debussy) (  ) 信誉:100  2002 方法好写!
      

  15.   

    vbFly你说什么效率接近DTS?batchmove?那绝对不是,可以马上做实验,数据越多越能看出差别,至少我用一万条数据就已经明显看出太大的差别了。用 BatchMove 你不会是按缺省的缓存设置导入Access的吧?一万条的确没有什么大的差别!
      

  16.   

    笑哥哥,您的程序在计时的时候有问题,我给您换了一下顺序,真实时间我测验一下,6500条数据,一分40秒附近。
    原程序:
         edit2.Text:=datetimetostr(time);
         adodataset2.EnableControls;
         adoquery1.UpdateBatch(arall);
    后程序:
         adodataset2.EnableControls;
         adoquery1.UpdateBatch(arall);
         edit2.Text:=datetimetostr(time);因为整个完成在UpdateBatch的时候非常耗时,您不能把这部分放到计时之外。
      

  17.   

    sorry................
    再看了一遍需求.
    ==================================================================
    但用户要求对这个数据集进行查询,我不会对数据集使用SQL
    ==================================================================
    我提出解决方案,不知是否可行:
    1:客户端用户进行查询的时候把查询条件回传到服务器端.在服务器端进行查询,只把符合条件的记录返回给客户端.
    2:如果仍然使用将大数据包传给客户的方法,不必把数据写到access中去.在内存中进行过滤也能达到查询的效果.而且可做到无论指定的是哪一个数据集的哪一列,(不需要在本地建立对应的access库.)都可以进行查询.
    ===================================================================
    http://netroom.hbu.edu.cn/personal/mudeen/quickcopy.exe
    ==================================================================
    这是新的测试版,呵呵.还有一些bug,不过对于普通查询已经够用了.
    =================================================================
    Try It
      

  18.   

    SQL Server 道出:
    backup database to disk='d:\abc.bak' with replace
      

  19.   

    man8888,如何把备份出来的数据库用代码还原到Access中?
      

  20.   

    用DTS作数据导入应是最快的办法,
    我建议你在打开SQL事件探查器,然后用SQL Server 2000的DTS向导,将SQL Server中的数据导入Access 2000导入完成后,逐条copy SQL事件探查器中记录的SQl执行语句。经过整理后,就可由用户自己调用这些SQL代码。
    很多SQL的功能都能用这种办法实现。
      

  21.   

    你的客户应该不会一天的数据量就有一万多条记录吧,为什么不只追加自上次追加后更新过的记录呢。在远程服务器的数据表中增加一个LastChangeTime(最后修改时间)字段,读取远程数据表的DataSet的查询语句这么写:
    select * from SqlTable where LastChangeTime>上次取得数据时间
      

  22.   

    呵呵,看来只有batchmove 符合您的要求了.
    BDE呀,真是让人又爱又恨.........
    不知道有没有Ado下面的类似batchmove的控件.
      

  23.   

    Select *into yy  from xx
    在SQL server中建立连接服务器这样很快的!
    但是好像要标准服务器板以上才支持!
      

  24.   

    manboo,不好意思,我知道的select * into yy from xx好像一般做创建新表用。笑哥哥,我知道SQL导出有一个library可以用,但Access导入的com或者api我就没有一点思路了,这就是这次想问的主要目的。用BatchMove也要20秒,可能是我机器不好,用batchmove的时候其他基本都停了,而Access得导入...对别的没有什么影响,我想做程序,无非就是想学东西,所以来问了,呵呵
      

  25.   

    使用batchmove确实存在这个问题.
    它使用批量移动数据的方法,容易停止响应.
    不像自己使用循环时可以用application.ProcessMessages来让程序响应其它操作.
      

  26.   

    不可思议的执行效率
    下面的这段代码(在内存中为数据集增加10000条记录)执行时间要30多秒
    procedure TForm1.BitBtn2Click(Sender: TObject);
    var
      aTimeS,aTimeE:double;
    begin
      if not AdoDataSet1.Active then AdoDataSet1.Active :=True;
      ClientDataSet1.DisableControls;
      ClientDataSet1.First;
      aTimeS:=GetTickCount();
      while not ClientDataSet1.Eof do
      begin
        AdoDataSet1.Insert;
        AdoDataSet1.FieldByName('Field1').AsString:=ClientDataSet1.FieldByName('Field1').AsString;
        AdoDataSet1.FieldByName('Field2').AsString:=ClientDataSet1.FieldByName('Field2').AsString;
        AdoDataSet1.FieldByName('Field3').AsString:=ClientDataSet1.FieldByName('Field3').AsString;
        AdoDataSet1.FieldByName('Field4').AsString:=ClientDataSet1.FieldByName('Field4').AsString;
        AdoDataSet1.FieldByName('Field5').AsString:=ClientDataSet1.FieldByName('Field5').AsString;
        AdoDataSet1.FieldByName('Field6').AsString:=ClientDataSet1.FieldByName('Field6').AsString;
        AdoDataSet1.FieldByName('Field7').AsString:=ClientDataSet1.FieldByName('Field7').AsString;
        AdoDataSet1.FieldByName('Field8').AsString:=ClientDataSet1.FieldByName('Field8').AsString;
        AdoDataSet1.FieldByName('Field9').AsString:=ClientDataSet1.FieldByName('Field9').AsString;
        AdoDataSet1.Post;
        ClientDataSet1.Next;
      end;
      ATimeE:=GetTickCount();
      Label1.Caption :=FloatToStr((ATimeE-aTimeS)/1000);
    end;
    最后的统计时间是37.354而下面这几行代码只是调用UpdateBatch将数据存盘,竟然要10多分钟的时间
    procedure TForm1.BitBtn3Click(Sender: TObject);
    var
      ATimeS,ATimeE:double;
    begin
      ATimeS:=GetTickCount();
      AdoDataSet1.UpdateBatch(arAll);
      ATimeE:=GetTickCount();
      Label2.Caption :=FloatToStr((ATimeE-aTimeS)/1000);
    end;
    统计的结果是598.912大家看看是什么原因,只是一个UpdateBatch啊,竟然要这么长时间
      

  27.   

    大家看看是什么原因,只是一个UpdateBatch啊,竟然要这么长时间
    ===================================================================
    呵呵,你的数据都保存在内存或者虚拟内存中,导致存盘时能够使用的内存不足.
    ==================================================================
    以上纯属猜测
      

  28.   

    Ado的updatebatch千万不要用,尤其是数据大的时候,我这么说是有根据的,不信你自己看Delphi是怎么调用哪个updatebatch的,跟自己一条条的写没有区别,而且中间验证很多.
      

  29.   

    Mudeen(笑哥哥)
    应该不是内存不足的问题,我曾试过每1000条存一次,效率也差不多
      

  30.   

    是的!很多事情交给服务器去处理好了再返回。服务器有足够好的性能与内存来计算。
    你说到的数据集也可以在服务器端查询好了再返回,真需要返回所有数据,你就只好将数据全部导入本地(无论用什么统一格式都可以),时而加以标志做比较有无数据更新,无则在本地查询,有则把服务器端的带有修改标志的数据导回本地,这我想应该不成问题了吧。(而导的过程都在服务器端进行,传输的数据量不大,哪么无论网速与用户都不该有问题)OK,做项目是需要实践与方案分析,CSDN讨论是个好地方。
    我是业余的,上班做网管。可以联系:QQ:4264362
    mailto: [email protected]
      

  31.   

    icewolf (夜叉王) 
       很关心你的问题。我在ACCESS之间倒数据5000条(有备注字段),花费了我1个多小时呀!(共155M)我猜测,你的10000条数据,数据量多大?你跟用户这样说:你在WINDOWS平台上,拷贝一个这么大的文件,需要多长时间?更何况数据库呢!还有一点提醒:ACCESS数据库第一次连接时间很长,以后,你即使关掉连接了,再建立连接也是很快的。
      

  32.   

    TOMWLD(笑天) 
       很简单,一个是在内存中操作
               一个是在硬盘中操作
       这个速度,你可以想象的。
      

  33.   

    icewolf(夜叉王) -〉
       咱们能不能看一下Batchmove的代码,然后自己写一个TADOBatchmove.我真觉得这玩艺好用,不过可惜ADO不能用!
      还有就是想问一下,您为什么用socket将数据传到本地,难道就是为了效率(这样效率会好多少?),用ADO的连结属性不行吗?用socket传过来后,还要很多麻烦的处理?您将传过来的数据直接就显示在DBGrid中吗?没有数据集组件怎么用Bacthmove?
      

  34.   

    LUOWENYONG(蓝色宝贝) ;
    您说的容易.
    batchmove的源码很容易看到.呵呵,但是实现的机制是针对BDE的........
    似乎不那么好改的.
    您知道李颖大侠写过的那个.....dbbackup的控件吗?也是针对BDE的,但是要改写成ado的太难了..所以他说'希望能够在他的有生之年能够写出来'......
      

  35.   

    rockynmc,不能采用你说的客户提请求,服务器分析的方法,第一不适用于线路少,客户多,速度慢的情况,第二取回数据后对数据的分析是很麻烦的,比如你考虑两个情况,其一删除过数据,其二更新过一条记录的时间。这两个都需要逐条比较,非常麻烦。cx1997,你有没有用access本身的导入做实验,看看速度如何?我就是看了那个速度觉得不想再写下去了。:)蓝色宝贝,我现在分别执行的需要的时间是:
    服务器端:取数据,压缩打包,一共300-400ms
    传送:20-30s
    写硬盘: 20-30s
    如果是用连接做,恐怕查一次就要差不多这么长时间吧。但我这样说是估计,没有试验依据,我没有用连接试过,明天试试。
    要用batchmove简单啊,你用个datasource转一下就行,就能用到ado中了。liuwl,我的错,确实csdn上不少问题都不是弱智问题。
      

  36.   

    今天看了关于压宝的介绍.也试了一下.发现一个问题;
    一个10.4m的access数据库原来用压缩软件可以压到不大于600K的呢.
    既然如此,为何不在服务器端直接把sql server 端把数据导入到access中去,然后压缩access数据库,把access数据库传输到客户端,客户端调用解压缩工具解压,然后连接到该access数据库.如此一来,在服务器端只需做少量的工作:
    导出到access->压缩->传输
    客户端的工作;接收->解压,然后就能查询了.这样做的话优点是不要在客户端导入数据,不要在客户端分发BDE,但是缺点是需要配合第三方的压缩工具进行操作.
    至于导出到access中,如果在服务器端的话,因为不是实时响应请求,对速度要求不会太高.如果客户是每小时要求更新一次数据的话,只需在这个小时内做一次压缩就行了.如果要注重效率,也很简单,SQL sverver是可以提供了语句导出到ole db数据源中的.不知道这种方法是否满足要求..........
    呵呵,要考试了,不写代码了.不过我觉得这样做肯定比用循环有效率.比分发BDE要少很多维护之苦.
      

  37.   

    To  zhanglaokan(侃哥) ;
      您下载这个东东试一下,看一下解压缩之后是否有10.5m
      压缩包大小是262k,里面有个authors表,它大概有60000条记录........
    http://netroom.hbu.edu.cn/personal/mudeen/dbdemos.zip
      

  38.   

    如果把ACCESS做为SQL的远程服务器,在SQL的存储过程中把数据“推”过去,应该是和DTS一个原理了吧?
      

  39.   

    笑哥哥,我就怕服务器端占用的资源太多,虽然这边不能说是实时,但对数据的更新要求还是比较高的,你想我一个上午差不多一万条记录,这一万条记录怎么来的,就是用户通过种种途径发布过来的,所以要求还是比较高的,我现在做的一分钟生成一个数据流,在服务器端,我明天测试一下,看直接导出到Access占资源情况。不过我觉得只要是磁盘操作,性能应该不会太理想。