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

swish

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

1、将A数据库A表的部分数据导入 B数据库B表中
【应用场景】
经常需要将A表的部分数据导入到B库的A表中,以前用循环插入 或是用数据库本身的导入导出,比较耗时,操作麻烦。
【原始做法】
循环插入
Code:
AdoQueryM.sql.text:=’select*fromA表’;
AdoQueryM.sql.Open;
WithAdoQueryM dobegin
  First;
  whilenotEofdobegin
  Inc(K);
  AdoQueryD.Append;
  fori:=0toFieldCount-1do
  begin
  AdoQueryD.FieldByName(Fields[i].FieldName).Value:=fieldByName(Fields[i].FieldName).Value;
  end;
  AdoQueryD.Post;
  Application.ProcessMessages;
  Next;
  end;
end;[/i][/i]

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

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

2、只复制指定列的内容到数据库
A表有50多个列,但自己只需要导入5个列到数据库中 ,QDB只需要将上面 1 中的
vQDataSet.CopyFrom(AdoQueryM);
改为:
vQDataSet.CopyFrom(adoquery1,’序号,编码,名称,状态,部门’);
既可。

3、大数据导入技巧-分页批量导入
【应用场景】
某表有10万行记录需要导入,非常耗时。
【解决方案】
采用QDataset的分页算法,批量插入
Code:
SQLDataSet,vData:TQDataSet;
adoMssql:=TQMSSQLConverter.Create(nil);//各种转换器
vData.PageSize:=1000;
fori:=0tovData.PageCount-1do
begin
vData.PageIndex:=i;
SQLDataSet.CopyFrom(vData,dcmview);//获取指定页的数据
adomssql.DataSet:=SQLDataSet;
conDB.Execute(adomssql.sql);
end;
4、本地ClientDataSet的日志文件导入到数据库
【应用场景】
本地有很多ClientDataSet产生的日志文件,需要导入到数据库中
【解决方案】
(1)、根据ClientDataSet的日志,动态产生表结构
Code:
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;[/i][/i][/i][/i][/i][/i][/i][/i][/i]

(2)、使用QDataSet+转换器 产生SQL语句并执行
Code:
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;