[QDB] 幽灵分享:QDataSet+TQMSSQLConverter 实战技巧

【注】本文由网友 幽灵 分享,由 swish 整理并重新编辑。

1、将A数据库A表的部分数据导入 B数据库B表中

【应用场景】

经常需要将A表的部分数据导入到B库的A表中,以前用循环插入 或是用数据库本身的导入导出,比较耗时,操作麻烦。

【原始做法】

循环插入

AdoQueryM.sql.text:=’select * from A表’;
AdoQueryM.sql.Open;
With AdoQueryM do begin
   First;
   while not Eof do begin
       Inc(K);
       AdoQueryD.Append;
       for i:=0 to FieldCount-1 do
       begin
          AdoQueryD.FieldByName(Fields[i].FieldName).Value:=fieldByName(Fields[i].FieldName).Value ;
       end;
       AdoQueryD.Post;
       Application.ProcessMessages;
       Next;
   end;
end;

【QDB】

AdoQueryM.sql.text:=’select * from A表’;
AdoQueryM.sql.Open;
vQDataSet.CopyFrom(AdoQueryM);
for i := 0 to vQDataSet.FieldDefs.Count-1 do
begin
     TQFieldDef(vQDataSet.FieldDefs[i]).Table:=’ A表’;
end;
adoMssql:=TQMSSQLConverter.Create(nil); //转换器
adoMssql.AllAsInsert:=true;
adomssql.DataSet:=vQDataSet;
ConnDB.Execute(adomssql.sql); //B数据库的连接

采用QDB的方法来转换数据,速度要比原始方法快了好几倍。

2、只复制指定列的内容到数据库

A表有50多个列,但自己只需要导入5个列到数据库中 ,QDB只需要将上面 1 中的

vQDataSet.CopyFrom(AdoQueryM);

改为:

vQDataSet.CopyFrom(adoquery1,’序号,编码,名称,状态,部门’);

既可。

3、大数据导入技巧-分页批量导入

【应用场景】

某表有10万行记录需要导入,非常耗时。

【解决方案】

采用QDataset的分页算法,批量插入

SQLDataSet ,vData:TQDataSet;
adoMssql:=TQMSSQLConverter.Create(nil); //各种转换器
vData.PageSize:=1000;
for i := 0 to vData.PageCount-1 do
begin
  vData.PageIndex:=i;
  SQLDataSet.CopyFrom(vData,dcmview); //获取指定页的数据
  adomssql.DataSet:=SQLDataSet;
  conDB.Execute(adomssql.sql);
end;

4、本地ClientDataSet的日志文件导入到数据库

【应用场景】

本地有很多ClientDataSet产生的日志文件,需要导入到数据库中

【解决方案】

(1)、根据ClientDataSet的日志,动态产生表结构

procedure TableCreate(vfn:string;vData:TQDataSet);
var
  ADataset:TQDataSet;
  i:Integer;
  s,sql:string;
begin
  conDB.execute('if object_id(N'''+vfn+ ''',N''u'') is not null  drop table '+vfn);
  ADataSet:=TQDataSet.Create(nil);
  sql:=Format('Create table %s (',[vfn])+slinebreak;
  try
      ADataset.Clone(vData);
      for i:=0 to ADataset.Fields.Count-1 do
      begin
      if ADataset.Fields[i].DataType in [ftString, ftMemo, ftFmtMemo, ftWideString] then
      begin
         s:=' varchar('+inttostr(ADataset.Fields[i].DataSize)+')'
      end
      else if ADataset.Fields[i].DataType in[ftSmallint, ftInteger, ftWord, ftAutoInc] then         s:=' integer'

      else if ADataset.Fields[i].DataType in[ftLargeInt] then
         s:=' bigint'
      else if ADataset.Fields[i].DataType=ftCurrency then
         s:=' money'
      else if ADataset.Fields[i].DataType in [ftDate, ftTime, ftDateTime] then
         s:=' datetime'
      else if ADataset.Fields[i].DataType in [ftBoolean] then
         s:=' bit'
      else if ADataset.Fields[i].DataType in [ftBCD] then
         s:=' money'
      else
         s:=' money';
        sql:=' '+sql+ADataset.Fields[i].FieldName+s+',';
      end;
      sql:=Copy(sql,1,Length(sql)-1)+')';
       conDB.execute(sql);
  finally
     //  ADataSet.Free;
  end;
end;

(2)、使用QDataSet+转换器 产生SQL语句并执行

ClientDataSetM.LoadFromFile(‘日志文件’);
vData.CopyFrom(ClientDataSetM);
--分页导入数据
SQLDataSet:=TQDataSet.Create(nil);
vData.PageSize:=1000;
for i := 0 to vData.PageCount-1 do
begin
  vData.PageIndex:=i;
  SQLDataSet.CopyFrom(vData,dcmview); //获取指定页的数据
  adomssql.DataSet:=SQLDataSet;
  conDB.Execute(adomssql.sql);
  end;

 

 

 

分享到: