ADO的数据泵
来源:互联网 发布:淘宝前十女装店 编辑:程序博客网 时间:2024/04/30 15:13
//==============================================================================// batCopy 先删除已存在的表,再创建新表,再往表中增加数据// batAppend 往已存在的表中追加数据// dsQuery 源数据集控件是TADOQUERY// dsTable 源数据集控件是TADOTABLE// 不同的数据库,关键只在datatypetoaccesstypeandsize(),即字段类型转换//==============================================================================unit ADOBatchMove;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, stdctrls,Forms, Dialogs,Db, ADODB;type TADOBatchMode = (batAppend, batCopy);type TADOSourceMode = (dsTable,dsQuery);type TADOBatchMove = class(TComponent)private FDESTADOQuery: TADOQuery; FDESTADOTable: TADOTable; FSOURCEADOQuery: TADOQuery ; FSOURCEADOTable: TADOTable; FADOConnection: TADOConnection; //目标数据库连接件 FStringList: TStringList; FMode:TADOBatchMode; FSourceMode:TADOSourceMode; function ADObatchmoveTabletoTableTest():boolean; function ADObatchmoveQuerytoTableTest():boolean; function ADOTableExistTest(ADOTableTest: TADOTable):boolean; function ADOTableCreatefromTable(ADOTablepara: TADOTable):boolean; function ADOTableCreatefromQuery(ADOTablepara: TADOTable):boolean; function ADOTableDatafromTable(ADOTablepara: TADOTable):boolean; function ADOTableDatafromQuery(ADOTablepara: TADOTable):boolean; procedure SETSOURCEADOQuery(Value: Tadoquery); procedure SETSOURCEADOTable(Value: TadoTable); function datatypetoaccesstypeandsize(ftdef:TFielddef):string; { Private declarations }protected { Protected declarations }public procedure ADObatchmoveTabletoTable(); procedure ADObatchmoveQuerytoTable(); procedure Execute; constructor Create(AOwner: TComponent); override; destructor Destroy; override; { Public declarations }published property SourceMode: TADOSourceMode read FSourceMode write FSourceMode; property Mode: TADOBatchMode read FMode write FMode; property SourceQuery: TADOQuery read FSOURCEADOQuery write SETSOURCEADOQuery ; property SourceTable: TADOTable read FSOURCEADOTable write SETSOURCEADOTable; property DestTable: TADOTable read FDESTADOTable write FDESTADOTable; { Published declarations }end;procedure Register;implementationuses Registry, TypInfo, unitgauge;procedure Register;begin RegisterComponents('ado', [TADOBatchMove]); //edit by cxgend;constructor TADOBatchMove.Create(AOwner: TComponent);begin inherited; FDestADOTable:= TADOTable.create(self); FDESTADOQuery:= TADOQuery.create(self); FSOURCEADOTable:= TADOTable.create(self); FSOURCEADOQuery:= TADOQuery.create(self); FSOURCEADOtable:= nil; FSOURCEADOQuery:= nil; FDestADOTable:= nil; FADOConnection:= TADOConnection.create(self); FStringList:= TStringList.create;end;destructor TADOBatchMove.Destroy;begin inherited;end;//==============================================================================// 转换DELPHI字段类型为ACCESS字段类型//==============================================================================function TADOBatchMove.datatypetoaccesstypeandsize(ftdef:TFielddef):string;begin with ftdef do begin case DataType of ftstring: Result:='varchar(100)'; ftWideString: Result:='varchar(100)'; ftsmallint: result:='integer'; ftinteger: Result:='integer'; ftfloat: Result:='double'; ftcurrency: result:='money'; ftbcd: Result:='decimal(18,2)'; ftboolean: result:='bit'; ftDateTime: Result:='datetime'; else Result:='varchar(100)'; end; end;end;procedure TADOBatchMove.SETSOURCEADOQuery(Value: Tadoquery);begin FSOURCEADOQuery := Value; FSOURCEADOtable:= nil; FSourceMode:=dsquery; if Value <> nil then Value.FreeNotification(Self);end;procedure TADOBatchMove.SETSOURCEADOTable(Value: TadoTable);begin FSOURCEADOtable := Value; FSOURCEADOQuery:= nil; FSourceMode:=dsTable; if Value <> nil then Value.FreeNotification(Self);end;{ 测试将要建立的数据表是否已经存在,如存在,则删除后重建 }function TADOBatchMove.ADOTableExistTest(ADOTableTest: TADOTable):boolean;var i:integer;begin result:=false; ADOTableTest.Close; FADOConnection.close; FADOConnection.loginprompt:=false; FADOConnection.connectionString:=ADOTableTest.connectionString; FADOConnection.open; FADOConnection.GetTableNames(FStringList, False); for i:=0 to FStringList.count-1 do begin if FStringList.Strings[i]=ADOTableTest.Tablename then begin result:=true; exit; end; end;end;function TADOBatchMove.ADOTableCreatefromTable(ADOTablepara: TADOTable):boolean;var i:integer;begin //下面利用源数据(ado表)创建新表 result:=false; FDESTADOQuery.connectionString:=ADOTablepara.connectionString; FSOURCEADOTable.open; FDESTADOQuery.sql.Clear; FDESTADOQuery.sql.add('create table '+ADOTablepara.Tablename +' ('); for i:=0 to FSOURCEADOTable.fielddefs.count-1 do begin if i< FSOURCEADOTable.fielddefs.count-1 then FDESTADOQuery.sql.add(FSOURCEADOTable.fielddefs[i].name+' '+ datatypetoaccesstypeandsize(FSOURCEADOTable.fielddefs[i]) +',') else FDESTADOQuery.sql.add(FSOURCEADOTable.fielddefs[i].name+' '+ datatypetoaccesstypeandsize(FSOURCEADOTable.fielddefs[i]) +' )'); end; FDESTADOQuery.execsql; FDESTADOQuery.close; result:=true;end;function TADOBatchMove.ADOTableDatafromTable(ADOTablepara: TADOTable):boolean;var i:integer;begin //下面从源表传输数据 result:=false; Frmgauge:=TFrmgauge.create(self); FSOURCEADOTable.open; Frmgauge.Gauge.MaxValue:=0; Frmgauge.ShowModal; Frmgauge.Gauge.MaxValue:=FSOURCEADOTable.RecordCount; ADOTablepara.active:=true; while not FSOURCEADOTable.eof do begin ADOTablepara.insert; for i:=0 to FSOURCEADOTable.fieldcount-1 do ADOTablepara.Fields.Fields[i]:=FSOURCEADOTable.Fields.Fields[i]; ADOTablepara.post; Frmgauge.Gauge.Progress:=FSOURCEADOTable.Recno; FSOURCEADOTable.next; end; ADOTablepara.close; FSOURCEADOTable.close; Frmgauge.Free; result:=true;end;function TADOBatchMove.ADOTableCreatefromQuery(ADOTablepara: TADOTable):boolean;var i:integer;begin result:=false; //下面利用源数据(ado查询)创建新表 FDESTADOQuery.connectionString:=ADOTablepara.connectionString; FDESTADOQuery.sql.Clear; FDESTADOQuery.sql.add('create table '+ ADOTablepara.Tablename +'('); for i:=0 to FSOURCEADOQuery.fielddefs.Count-1 do begin if i<FSOURCEADOQuery.fielddefs.Count-1 then FDESTADOQuery.SQL.Add(FSOURCEADOQuery.fielddefs[i].Name+' '+ datatypetoaccesstypeandsize(FSOURCEADOQuery.fielddefs[i])+',') else FDESTADOQuery.SQL.Add(FSOURCEADOQuery.fielddefs[i].name+' '+ datatypetoaccesstypeandsize(FSOURCEADOQuery.fielddefs[i])+')'); end; FDESTADOQuery.execsql; FDESTADOQuery.close; result:=true;end;function TADOBatchMove.ADOTableDatafromQuery(ADOTablepara: TADOTable):boolean;var i:integer;begin result:=false; //下面从源查询传输数据 Frmgauge:=TFrmgauge.create(self); FSOURCEADOQuery.open; ADOTablepara.Open; FSOURCEADOQuery.First; while not FSOURCEADOQuery.eof do begin ADOTablepara.insert; for i:=0 to FSOURCEADOQuery.fieldcount-1 do begin ADOTablepara.Fields.Fields[i]:=FSOURCEADOQuery.Fields.Fields[i]; end; ADOTablepara.post; Frmgauge.Gauge.MaxValue:=FSOURCEADOQuery.RecordCount; //显示进度条 Frmgauge.Gauge.Progress:=FSOURCEADOQuery.Recno; Frmgauge.Show; FSOURCEADOQuery.next; end; ADOTablepara.close; Frmgauge.Free; //释放进度条窗口 result:=true;end;function TADOBatchMove.ADObatchmoveTabletoTableTest():boolean;var sourcefield,destfield:string; i:integer;begin if Fmode=batAppend then begin result:=false; FSOURCEADOTable.active:=true; FDESTADOTable.active:=true; IF FSOURCEADOTable.active=true AND FDESTADOTable.active=true THEN begin if FSOURCEADOTable.fieldcount=FDESTADOTable.fieldcount then begin result:=true; for i:=0 to FSOURCEADOTable.fieldcount-1 do begin sourcefield:=datatypetoaccesstypeandsize(FSOURCEADOTable.fielddefs[i]); destfield:=datatypetoaccesstypeandsize(FDESTADOTable.fielddefs[i]); if sourcefield<>destfield then result:=false; end; end; end; end else begin if ADOTableExistTest(FDESTADOTable) then result:=true else result:=false; end;end;procedure TADOBatchMove.ADObatchmoveTabletoTable();var i:integer;begin if Fmode=batAppend then begin if ADObatchmoveTabletoTableTest then begin FSOURCEADOTable.Open; FDESTADOTable.open; while not FSOURCEADOTable.eof do begin FDESTADOTable.insert; for i:=0 to FSOURCEADOTable.fieldcount-1 do FDESTADOTable.Fields.Fields[i]:=FSOURCEADOTable.Fields.Fields[i]; FDESTADOTable.post; FSOURCEADOTable.next; end; FSOURCEADOTable.close; FDESTADOTable.close; end else showmessage('传输数据失败!'); end else begin if ADObatchmoveTabletoTableTest then begin FDESTADOTable.close; FDESTADOQuery.connectionString:=FDESTADOTable.connectionString; FDESTADOQuery.SQL.Clear; FDESTADOQuery.sql.Add('drop table '+FDESTADOTable.TableName); FDESTADOQuery.execsql; ADOTableCreatefromTable(FDESTADOTable); ADOTableDatafromTable(FDESTADOTable); end else begin ADOTableCreatefromTable(FDESTADOTable); ADOTableDatafromTable(FDESTADOTable); end; end;end;function TADOBatchMove.ADObatchmoveQuerytoTableTest():boolean;var sourcefield,destfield:string; i:integer;begin result:=false; if Fmode=batAppend then //批增加 begin result:=false; FSOURCEADOQuery.active:=true; FDESTADOTable.active:=true; IF FSOURCEADOQuery.active=true AND FDESTADOTable.active=true THEN begin if FSOURCEADOQuery.fieldcount=FDESTADOTable.fieldcount then begin result:=true; for i:=0 to FSOURCEADOQuery.fieldcount-1 do begin sourcefield:=datatypetoaccesstypeandsize(FSOURCEADOQuery.fielddefs[i]); destfield:=datatypetoaccesstypeandsize(FDESTADOTable.fielddefs[i]); if sourcefield<>destfield then result:=false; end; end; end; end else begin //批复制 if ADOTableExistTest(FDESTADOTable) then result:=true else result:=false; end;end;//==============================================================================// drop table 改在分组统计之后立即进行// 放在此处不合理//==============================================================================procedure TADOBatchMove.ADObatchmoveQuerytoTable();var i:integer;begin if Fmode=batAppend then //批增加 begin if ADObatchmoveQuerytoTableTest then begin FSOURCEADOQuery.open; FDESTADOTable.open; while not FSOURCEADOQuery.eof do begin FDESTADOTable.insert; for i:=0 to FSOURCEADOQuery.fieldcount-1 do begin FDESTADOTable.Fields.Fields[i]:=FSOURCEADOQuery.Fields.Fields[i]; end; FDESTADOTable.post; FSOURCEADOQuery.next; end; FDESTADOTable.close; FSOURCEADOQuery.close; end else showmessage('传输数据失败!'); end else begin //批复制 if ADObatchmoveQuerytoTableTest then //如果数据表已经存在,则删除重建 begin FDESTADOTable.close; FDESTADOQuery.connectionString:=FDESTADOTable.connectionString; FDESTADOQuery.SQL.Clear; FDESTADOQuery.sql.Add('drop table '+FDESTADOTable.TableName); FDESTADOQuery.execsql; ADOTableCreatefromQuery(FDESTADOTable); ADOTableDatafromQuery(FDESTADOTable); end else begin ADOTableCreatefromQuery(FDESTADOTable); ADOTableDatafromQuery(FDESTADOTable); end; end;end;//==============================================================================// 此处必须延时,否则之后的分组统计有误//==============================================================================procedure TADOBatchMove.Execute;begin if fsourcemode=dsTable then ADObatchmoveTabletoTable else ADObatchmoveQuerytoTable; Sleep(1000); end;end.