大批量从文本文件导入数据库导致程序像死了一样!,应该如何优化?(100分)

  • 主题发起人 梦菲斯
  • 开始时间

梦菲斯

Unregistered / Unconfirmed
GUEST, unregistred user!
大约有15000条左右记录,导入的时候程序像死了一样,但过一段时间后看数据库,数据已经导到
数据库中了,请问应该如何优化?还有AssignFile能不能判断文本文件共有几行?
代码如下:
//导入商品综合归类数据
procedure TfrmImport.ImportComplex;
var
TextFileVar:Textfile ;
fileN:string;
sCodet,sCodes,sName,sLowRate,sHighRate,temp:string;
sRate,sMark :string;
sTableName : string;
sSql : string;
connComm : TAdoCommand ;
i : integer ;
begin
if opendialog1.execute then
begin
sTableName := 'colligation';
FileN:=opendialog1.FileName;
If FileN='' Then Exit;
AssignFile ( TextFileVar , FileN ) ;
Reset(TextFileVar);
while not SeekEof(TextFileVar) do
begin
ConnComm := TAdoCommand.Create(self);
connComm.Connection := Dm.AppConn ;
Readln(TextFileVar,temp ) ;
scodet:=copy(temp, 1,8);
sCodes:=copy(temp,9,2);
sName:=copy(temp, 17,30);
sLowRate :=copy(temp,48,5);
sHighRate :=copy(temp,54,5);
sRate := copy(temp,60,5);
sMark := copy(temp,190,1);
sSql:= 'insert into colligation(Code_t,Code_s,Ware_Name,low_rate,';
sSql:=sSql+ 'High_rate,Tax_rate,Control_Mark) values('+chr(39);
sSql:=sSql+sCodet+chr(39)+','+chr(39)+scodes+chr(39)+','+chr(39);
sSql:=sSql+sName+chr(39)+','+sLowRate+','+sHighRate+',';
sSql:=sSql+sRate+','+chr(39)+sMark+chr(39)+')';
connComm.CommandText:='';
connComm.CommandText :=sSql;
ConnComm.Execute(sSql);
end;
closeFile(TextFileVar);
ShowMessage('数据成功导入到商品综合归类表中!');
btnImport.Enabled := true ;
SB.Panels[0].Text :='数据导入成功!';
end;
end;
 
用线程可以解决象‘死了一样的’问题
 
用StringList多好,Count判断行数,加个滚动条不就行了?
query方面用参数,是不是快点?
 
加个进度条,我昨天一次导了180M的图片到sql server 也没感觉要死机,呵呵
 
用stringlist,你可能先放入數據集,再批量更新快多了。
還要源碼嗎?答應給我100分我就給你源碼
 
fxjpost兄,分不是问题,发过来看看?谢了!
 
to 幸福鸟,
用线程,怎么用,我也想学习一下!:)
 
TStringlist + 多线程
 
能不能给一点详细的例子,小弟用得不熟!
 
在循环体中加入Application.ProcessMessages;
 
这两句可以拿到循环外,
ConnComm := TAdoCommand.Create(self);
connComm.Connection := Dm.AppConn ;
这句去掉
connComm.CommandText:='';

io操作是很耗时的,如果要解决阻塞问题,还是用线程吧。
 
给点线程的例子吧!分不够可再加!
 
大千世界无奇不有,Borland免费送的栗子不要,却要掏钱买。
 
在循环体中 例如每次循环了1000此后 :加入Application.ProcessMessages;
//这样就不会像死了一样//我是这样做的////完全没有问题!!!!!!!

 
如果你的数据库是SQL SERVER,不妨看看DTS,用那个导文本是非常快的。
 
没错,就是用线程
 
procedure TForm1.Button3Click(Sender: TObject);
var
i :integer;
begin
for i :=2000212 to 2000311 do
begin
//用Ado异常来进行插入,注意要重新进行查询,
//定下总的页面数
//不然插入完了重新定总页数
//异步做插入删除感觉不错哦,哈哈,数据重新查询还是可以查到
ADOConnection1.BeginTrans;
ADOQuery3.Close;
//eoAsyncFetchNonBlocking ,eoAsyncExecute ,eoAsyncFetch
ADOQuery3.ExecuteOptions :=[eoAsyncFetchNonBlocking];
ADOQuery3.SQL.Text :='insert into aa values('+#39+inttostr(i)+#39+','
+#39+'zqs12'+#39+')';
try
ADOQuery3.ExecSQL;
except
ADOQuery3.Close;
continue;
end;
try
ADOConnection1.CommitTrans;
except
ADOQuery3.Close;
ADOConnection1.RollbackTrans;
end;
end;
end;
 
我觉得你可以考虑ADO异步模式进行插入
插入方案建议用分段先存入一个临时表(当你插入的表数据很大,
而你又往里面插大数据,速度肯定慢)。然后调用存储过程把
临时表的数据进行插入(临时表保存的是一段的数据)
 
多人接受答案了。
 
顶部