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

Discussion in 'QDAC' started by swish, Nov 12, 2015.

Tags:
  1. swish

    swish Staff Member Moderater

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

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

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

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

    2、只复制指定列的内容到数据库
    A表有50多个列,但自己只需要导入5个列到数据库中 ,QDB只需要将上面 1 中的
    改为:
    既可。

    3、大数据导入技巧-分页批量导入
    【应用场景】
    某表有10万行记录需要导入,非常耗时。
    【解决方案】
    采用QDataset的分页算法,批量插入
    Code (Text):
    1. SQLDataSet,vData:TQDataSet;
    2. adoMssql:=TQMSSQLConverter.Create(nil);//各种转换器
    3. vData.PageSize:=1000;
    4. fori:=0tovData.PageCount-1do
    5. begin
    6. vData.PageIndex:=i;
    7. SQLDataSet.CopyFrom(vData,dcmview);//获取指定页的数据
    8. adomssql.DataSet:=SQLDataSet;
    9. conDB.Execute(adomssql.sql);
    10. end;
    4、本地ClientDataSet的日志文件导入到数据库
    【应用场景】
    本地有很多ClientDataSet产生的日志文件,需要导入到数据库中
    【解决方案】
    (1)、根据ClientDataSet的日志,动态产生表结构
    Code (Text):
    1. procedure TableCreate(vfn:string;vData:TQDataSet);
    2. var
    3.   ADataset:TQDataSet;
    4.   i:Integer;
    5.   s,sql:string;
    6. begin
    7.   conDB.execute('if object_id(N'''+vfn+ ''',N''u'') is not null  drop table '+vfn);
    8.   ADataSet:=TQDataSet.Create(nil);
    9.   sql:=Format('Create table %s (',[vfn])+slinebreak;
    10.   try
    11.       ADataset.Clone(vData);
    12.       for i:=0 to ADataset.Fields.Count-1 do
    13.       begin
    14.       if ADataset.Fields[i].DataType in [ftString, ftMemo, ftFmtMemo, ftWideString] then
    15.       begin
    16.          s:=' varchar('+inttostr(ADataset.Fields[i].DataSize)+')'
    17.       end
    18.       else if ADataset.Fields[i].DataType in[ftSmallint, ftInteger, ftWord, ftAutoInc] then         s:=' integer'
    19.  
    20.       else if ADataset.Fields[i].DataType in[ftLargeInt] then
    21.          s:=' bigint'
    22.       else if ADataset.Fields[i].DataType=ftCurrency then
    23.          s:=' money'
    24.       else if ADataset.Fields[i].DataType in [ftDate, ftTime, ftDateTime] then
    25.          s:=' datetime'
    26.       else if ADataset.Fields[i].DataType in [ftBoolean] then
    27.          s:=' bit'
    28.       else if ADataset.Fields[i].DataType in [ftBCD] then
    29.          s:=' money'
    30.       else
    31.          s:=' money';
    32.         sql:=' '+sql+ADataset.Fields[i].FieldName+s+',';
    33.       end;
    34.       sql:=Copy(sql,1,Length(sql)-1)+')';
    35.        conDB.execute(sql);
    36.   finally
    37.      //  ADataSet.Free;
    38.   end;
    39. end;[/i][/i][/i][/i][/i][/i][/i][/i][/i]

    (2)、使用QDataSet+转换器 产生SQL语句并执行
    Code (Text):
    1. ClientDataSetM.LoadFromFile(‘日志文件’);
    2. vData.CopyFrom(ClientDataSetM);
    3. --分页导入数据
    4. SQLDataSet:=TQDataSet.Create(nil);
    5. vData.PageSize:=1000;
    6. for i := 0 to vData.PageCount-1 do
    7. begin
    8.   vData.PageIndex:=i;
    9.   SQLDataSet.CopyFrom(vData,dcmview); //获取指定页的数据
    10.   adomssql.DataSet:=SQLDataSet;
    11.   conDB.Execute(adomssql.sql);
    12.   end;