我要实现的是一个类似远程查询的功能,但因为不能开发数据库端口,所以想通过自己开的端口来传输查询结果。先是用ADOQuery执行一条SQL查询,然后用ADOQuery.SaveToFile,将查询结果保存到文件。将该文件传送给远程,远程收到后,用ADODataSet.LoadFromFile加载数据(ADOQuery也可以的),然后将这些数据写入数据表。插入到数据表中的代码是这样的ADOQuery.SQL.Add('select * from TempTable'); // 打开这张表
ADOQuery.Open;
ADODataSet.LoadFromFile('C:\数据文件.tmp');
ADODataSet.First;
while not ADODataSet.Eof do begin  ADOQuery.Append;
  ADOQuery.FieldByName('').AsString:= ADODataSet.FieldByName('').AsString;
  //.....其他字段
  ADOQuery.Post;  ADODataSet.Next;
end;但这样做效率很低,而且CPU占用很大,记录条数一多,就往往会有好长时间都是100的CPU。
请问有没有更加简便高效的方法?

解决方案 »

  1.   

    导出的时候控制一下格式生成文件,然后异构数据库导入
    我做过30万条数据导入access大概10秒
      

  2.   

    导出的时候生成的文件格式有2个(pfADTG, pfXML),是不是选pfXML?异构数据库导入是什么意思?
      

  3.   

    我导入的是MS SQL Server数据库,感觉效率低的原因是在
    while not ADODataSet.eof do begin
      ADOQuery.append;  ADOQuery.post;
      ADODataSet.next;
    end;用这种循环,总感觉效率很低
      

  4.   

    哦,忘了说,我2边的数据库都是MS SQL Server的
      

  5.   

    异构数据库可以到大富翁看看,一个最简单的例子
    ADOConnection.Execute('Select * Into abcd From [Text;Database=c:\temp].aaaa.txt'); abcd表只有一个字段,文本类型
    aaaa.txt里面的格式是
    111111
    22222222
    33333
    444444
    555555
    ......
    你可以试一试在aaaa中加入10万条记录然后导入
      

  6.   

    全部数据加入QUERY,放到最后再POST,这样应该会效率一点
    while not ADODataSet.Eof do begin  ADOQuery.Append;
      ADOQuery.FieldByName('').AsString:= ADODataSet.FieldByName('').AsString;
      //.....其他字段  ADODataSet.Next;
    end;
    ADOQuery.Post;
      

  7.   

    To: brightyang(其实我是一个程序员)
        我其实就是想问怎么样批量存入。能说说你的方法吗?To: xiaoxinghappy(清晨好凉,被窝好暖:)
        你这样写是不行的,必须一行一行的Post。
      

  8.   

    To: ccdarkness(亲亲我的宝贝) 
        你说的方法我试过了,但好像都是支持Access数据库的。MS SQL SERVER好像支持不了。导入:
    ADOConnection1.execute('select * into aa from [text;database=d:\].bbb');
    导出:
    ADOConnection1.execute('select * into [text;database=d:\].aa from bbb');我ADOConnection1连接的是MS SQL SERVER 数据库,执行的时候总是说 
    数据库 Text;Database=d:\ 不存在
      

  9.   

    里面的方法试过很多,我也做过,我是用线程完成的,成批的执行SQL语句。
    效率会快点
    有人说可以用CLIENTDATASET,但我没有成功。
      

  10.   

    我刚刚写代码测试了下,用的是网上一名叫邹建的方法(很多地方都是帖了他的方法)存储过程如下(转贴邹建的方法):
    if exists(select 1 from sysobjects where name='File2Table' and objectproperty(id,'IsProcedure')=1)
     drop procedure File2Table
    Gocreate procedure File2Table
      @servername varchar(200),  --服务器名
      @username varchar(200),    --用户名,如果用NT验证方式,则为空''
      @password varchar(200),    --密码
      @filename varchar(1000),   --目录名+文件名
      @tbname varchar(500)='',   --数据库..表名
      @isout bit=1,              --1为导出(默认),0为导入
      @fdsplit varchar(10)='\t', --字段分隔符,默认为制表符
      @rowsplit varchar(10)='\n' --记录分隔符,默认为回车符
    as
      declare @sql varchar(8000)  set @sql='bcp "'+@tbname
      +case when @isout=1 then '" out' else '" in' end
      +' "'+@filename+'" /c' +' /S"'+@servername
      +case when isnull(@username,'')='' then '' else '" /U"'+@username end
      +'" /P"'+isnull(@password,'')+'"'
      +' /t"'+@fdsplit+'"'
      +' /r"'+@rowsplit+'"'exec master..xp_cmdshell @sqlGO
    ///////////////下面是我的测试代码/////////////////
    procedure TForm1.Button3Click(Sender: TObject);
    begin
      with ADOStoredProc1 do begin
        Close;
        Prepared:= False;
        ProcedureName:= 'File2Table';
        Parameters.Clear;
        Parameters.Refresh;    Parameters.ParamByName('@servername').Value:= '127.0.0.1';
        Parameters.ParamByName('@username').Value:= 'sa';
        Parameters.ParamByName('@password').Value:= '123456';
        Parameters.ParamByName('@filename').Value:= 'D:\data.txt';
        Parameters.ParamByName('@tbname').Value:= 'local..ps_TempTable';
        Parameters.ParamByName('@isout').Value:= 0;  // 这个值为1的话就是导出,0是导入
        Prepared:= True;
        ExecProc;
      end;
    end;连接数据库后,第一次执行导出/导入,都能正常运行,但第二次执行就会报下面的错误
    Access violation at address 4DE433E4 in module 'SQLOLEDB.DLL'. Read of address 00000018而每次执行都重新创建StoredProc,结束再释放就没问题。有没有方法能让他不要重复创建/释放啊? 执行前StoredProc.Close好像也没用。
      

  11.   

    对了,另外问下,上面的存储过程调用的是一个外部工具BCP,
    那执行存储过程中,ExecProc函数执行完毕,是不是代表存储过程也执行完毕了,还是说只是调用完毕,存储过程有可能还在执行中?如果是只是调用了外部BCP工具,那怎么样去得到存储过程执行完毕的事件。
      

  12.   

    txt导入SQLServerselect * from OpenRowset('MSDASQL', 'Driver={Microsoft Text Driver (*.txt; *.csv)};
    DefaultDir=c:\temp;','select * from aaaa.txt')原文
    http://www.delphibbs.com/delphibbs/dispq.asp?lid=1691966