大批量数据处理问题(从本地文件写入数据库) ( 积分: 200 )

J

JOL

Unregistered / Unconfirmed
GUEST, unregistred user!
本地文件为xml格式,具体格式如下:
<?xml version="1.0" standalone="yes"?>
<DATAPACKET Version="2.0">
<METADATA>
<FIELDS>
<FIELD attrname="GTHCODE" fieldtype="string" SUBTYPE="FixedChar" WIDTH="8"/>
<FIELD attrname="RECDATE" fieldtype="dateTime"/>
<FIELD attrname="ICN" fieldtype="string" WIDTH="16"/>
<FIELD attrname="TIM" fieldtype="string" WIDTH="14"/>
.....
</FIELDS>
<PARAMS DEFAULT_ORDER="8 11 7 10" LCID="1033"/>
</METADATA>
<ROWDATA>
<ROW RECDATE="20050117" ICN="5100000104977021" TIM="20050117063444" TFARE="2" CARDTYPE="03" SAM="00008666" DSN="122400"/>
....
</ROWDATA>
</DATAPACKET>
该文件数据量比较庞大,每个文件有20多万条数据,如何用比较快捷的方式将数据提交到数据库呢?
 
本地文件为xml格式,具体格式如下:
<?xml version="1.0" standalone="yes"?>
<DATAPACKET Version="2.0">
<METADATA>
<FIELDS>
<FIELD attrname="GTHCODE" fieldtype="string" SUBTYPE="FixedChar" WIDTH="8"/>
<FIELD attrname="RECDATE" fieldtype="dateTime"/>
<FIELD attrname="ICN" fieldtype="string" WIDTH="16"/>
<FIELD attrname="TIM" fieldtype="string" WIDTH="14"/>
.....
</FIELDS>
<PARAMS DEFAULT_ORDER="8 11 7 10" LCID="1033"/>
</METADATA>
<ROWDATA>
<ROW RECDATE="20050117" ICN="5100000104977021" TIM="20050117063444" TFARE="2" CARDTYPE="03" SAM="00008666" DSN="122400"/>
....
</ROWDATA>
</DATAPACKET>
该文件数据量比较庞大,每个文件有20多万条数据,如何用比较快捷的方式将数据提交到数据库呢?
 
先试试用clientdataset1.LoadFromFile(*.xml)能否打开,如果能打开就有办法了
 
可以用楼上的办法~
 
可以用clientDataSet.loadFromFile方法读,之后呢?还请blyb大虾告知。谢谢
 
用delphi自帶的工具“XML Mapper”來做呀。
 
对于XML的文档,我原来自己尝试过用ADOQUERY1来加载文件后再一条条记录循环后插入到表中,代码如下:
//function TDataModule2.AddDataBase(SQLs: string): boolean;
//var
// ADOQ: TADOQuery;
//begin
// Result := false;
// ADOQ := TADOQuery.Create(nil);
// try
// ADOQ.Connection := ADOConnection1;
// with ADOQ do
// begin
// ADOConnection1.BeginTrans;
// try
// Close;
// SQL.Clear;
// SQL.Text := SQLs;
// ExecSQL;
// ADOConnection1.CommitTrans;
// Result := true;
// except
// ADOConnection1.RollbackTrans;
// end;
// end;
// finally
// ADOQ.Free;
// end;
//end;
在实际运用中,效果不是很好,运行较慢。大慨一万条记录需要六、七分钟的
后来,我尝试用ADO的原生对象来做,代码如下
function TDataModule2.AddDataBase(const Recordset: _Recordset;
Gg: TGauge): boolean;
var
AdoRecordSet: variant;
FConnectionObject: _Connection;
i: integer;
begin
result := false;
if Recordset = nil then
Exit;
AdoRecordSet := CreateOleObject('ADODB.RecordSet');
ADOConnection1.Connected := True;
FConnectionObject := ADOConnection1.ConnectionObject;
AdoRecordSet.CursorLocation := clUseClient;
AdoRecordSet.open('select * from carddata where 1=2', FConnectionObject,
adOpenStatic, adLockOptimistic, AdCmdText);
try
Gg.MaxValue := Recordset.RecordCount;
while not Recordset.eof do
begin
Application.ProcessMessages;
AdoRecordSet.AddNew;
try
for I := 0 to Recordset.Fields.Count - 1 do //Iterate
begin
AdoRecordSet.fields.value := Recordset.Fields.Value;
end; //for
AdoRecordSet.Update;
except

end;
Gg.Progress := Gg.Progress + 1;
Recordset.MoveNext;
end;
result := true;
finally
AdoRecordSet.Close;
end;
end;
用了这个方法后,收到了较好的效果,同样的记录集,十几秒钟就完成了。你可以试一下看看的。
 
不好意思,一直没能上来回复。

经过测试在大数量的情况下,clientdataset的运行速度不怎样,使用clientdataset.next来读取数据,就算什么都不干,每9分钟大概只能读取2w条数据。所以瓶颈不是在写数据库,而是在读的过程。
不知大虾有何良策?
 
如果是用我上面的法子来读数据源会不会快一些呢?我自己没有试过二十万的数据源.
 
顶部