我要修改一个表中的数据,用了两个循环,其中ADODATASET1有6000条记录,ADODATASET2有9000条记录。外循环遍历ADODATASET1的记录,内循环遍历ADODATASET2的记录,程序运行时内循环正常,但外循环的进度条显示很慢,而且运行十分锺左右,提示OUT OF MEMORY,程序挂起。内循环遍历一次,速度很快,而外循环很慢,(只有6000条记录).已排除病毒存在的可能。我的程序如下:其中用了两个PROGRESSBAR,分别显示遍历进度。
procedure TForm2.Button1Click(Sender: TObject);
var
i,j:integer;
begin
    adoconnection1.Connected:=true;
    adodataset1.Close;
    adodataset2.Close;
    adodataset2.CommandText:='select * from danhao where dm=''ow''';
    adodataset2.Open;
    adodataset1.CommandText:='select * from transfer';
    adodataset1.Open;
    showmessage('共有'+inttostr(adodataset2.recordcount)+'记录要调整');
    progressbar2.Min:=0;
    progressbar1.Min:=0;
    progressbar1.Max:=adodataset1.RecordCount;
    progressbar2.Max:=adodataset2.RecordCount;
    adodataset1.First;
    for i:=1 to adodataset1.recordcount  do
    begin
        progressbar2.Min:=0;
        adodataset2.First;
        for j:=1 to adodataset2.recordcount do
        begin
               if adodataset2.Fieldbyname('hscode').Value=adodataset1.FieldByName('hscode').Value then
                  adodataset2.Fieldbyname('dm').Value:='O'+adodataset1.FieldByName('hscode').Value;
               progressbar2.Position:=j;
               next;
        end;
        adodataset2.Edit;
        adodataset2.Post;
        progressbar1.Position:=i;
        adodataset1.Next;
    end;
    showmessage('转换完成.');
end;

解决方案 »

  1.   

    内外循环加起来有6000*9000=54000000, 5千万啊,当然慢了。
    不要这样在程序里面用循环来做连接查找。
    内循环中用Sql语句进行查找连接吧。
      

  2.   

    你和我刚学Delphi时用的方法一样,
    这种循环肯定慢了,它进行了大量的I/O操作。所以建议你吧上述代码改写成SQL语句(用TQuery控件)或写存储过程。当时我写的代码和你写的代码差不多,查询起来要30秒,后来改成SQL语句,只需2秒钟,你可以试试。
      

  3.   

    写SQL语句,将这两个数据集通过一个数据源做关联,试试。
      

  4.   

    用Sql语句可以快一点,我原来作的数据比你的大好多,也没有这么慢, 进度条是不是挺浪费资源? 不敢确定,不过我原来只用Label显示了一下处理的纪录序号而已
      

  5.   

    谢谢。内循环已改SQL,可以运行了。但编译后的EXE文件运行时要,程序中途会无反应,在DELPHI下已正常运行了。程序修改如下:
    procedure TForm2.Button1Click(Sender: TObject);
    var
    aHscode,aDM:string;
    i,j:integer;
    begin
        adoconnection1.Connected:=true;
        adodataset1.Close;
        adodataset1.CommandText:='select * from transfer';
        adodataset1.Open;
        progressbar1.Min:=0;
        progressbar1.Max:=adodataset1.RecordCount;
        adodataset1.First;
        for i:=1 to adodataset1.recordcount  do
        begin
            aDM:='O'+adodataset1.fieldbyname('dm').value;
            aHscode:=adodataset1.fieldbyname('hscode').value;
            with adoquery1 do
            begin
               close;
               sql.clear;
               sql.add('update danhao set dm='''+aDM+''' where hscode='''+aHscode+'''');
               ExecSQL;
            end;
            progressbar1.Position:=i;
            adodataset1.Next;
        end;
        showmessage('转换完成.');
    end;
      

  6.   

    update table2 set DM='0'+(select table1.hscode from table1 ,table2 where table2.hscode=table1.hscode )
      

  7.   

    >>但编译后的EXE文件运行时要,程序中途会无反应
    在循环体内加上:Application.proccessMessage;