现在需要循环将5000多条记录插入到数据库的表中,一共三个字段,记录条数在5000左右..
点击按钮一次性插入.我现在做的只是在数据库中做好存储过程,然后在客户端调用。
存储过程名:sp_addItem , 三个参数,最为插入字段的值客户端程序:
procedure TForm1.ADDitemRelationDesc(ANo,Aname,Astatus:String); //添加数据
var
adoquery1:Tadoquery;
begin
adoquery1:=Tadoquery.Create(nil);
try
if not applySolutionDM.ADOConnection1.Connected then
applySolutionDM.ADOConnection1.Open;
adoquery1.Connection:=ApplysolutionDM.ADOConnection1;
With adoquery1 do
begin
close;
sql.clear;
sql.add('Execute sp_addItem :tmpNo,:tmpName,:tmpStatus');
parameters.parambyname('tmpNo').Value:=ANo;
parameters.ParamByName('tmpName').Value:=AName;
parameters.ParamByName('TmpStatus').Value:=Astatus;
execsql;
end;
finally
adoquery1.Free;
end;现在这样的方法,插入的话,大概需要20秒左右..
有没有更好的解决方法嘛? 在循环插入时候,调用如上的代码,不断的动态创建adoquery 有没什么影响?另外,小问一下 多线程能否用到当前的操作中 。谢谢!
点击按钮一次性插入.我现在做的只是在数据库中做好存储过程,然后在客户端调用。
存储过程名:sp_addItem , 三个参数,最为插入字段的值客户端程序:
procedure TForm1.ADDitemRelationDesc(ANo,Aname,Astatus:String); //添加数据
var
adoquery1:Tadoquery;
begin
adoquery1:=Tadoquery.Create(nil);
try
if not applySolutionDM.ADOConnection1.Connected then
applySolutionDM.ADOConnection1.Open;
adoquery1.Connection:=ApplysolutionDM.ADOConnection1;
With adoquery1 do
begin
close;
sql.clear;
sql.add('Execute sp_addItem :tmpNo,:tmpName,:tmpStatus');
parameters.parambyname('tmpNo').Value:=ANo;
parameters.ParamByName('tmpName').Value:=AName;
parameters.ParamByName('TmpStatus').Value:=Astatus;
execsql;
end;
finally
adoquery1.Free;
end;现在这样的方法,插入的话,大概需要20秒左右..
有没有更好的解决方法嘛? 在循环插入时候,调用如上的代码,不断的动态创建adoquery 有没什么影响?另外,小问一下 多线程能否用到当前的操作中 。谢谢!
不断的动态创建adoquery这个不好,对速度肯定有影响。只需创建一次就够了,然后循环执行存储过程即可可以使用多线程,尤其是在数据量很大或要求速度很快的情况下
而这个连接过程比较消耗资源。
另外,动态的创建组件也是比较消耗资源的。最好用原生ado,建立长连接,建立一次连接之后,组好50个左右的insert语句,一起执行,执行完不关闭连接,继续组insert语句
这样能够有效的提高效率。动态创建adoquery就不要想了。直接使用SQL语句或者使用append的方式都可以。
append最后也是转化为sql语句方式执行的。
多线程未必快,因为还要考虑数据库对数据的锁和解。
按你上面的意思是批理執行 AddItemRelationDesc 吧,為什麼指量傳入 ; Insert into 語句,不是更好點。
这样做非常不好。
sql.clear;
sql.add('Execute sp_addItem :tmpNo,:tmpName,:tmpStatus');
一定要提到循环外面来! 这样可以从20秒减少到5秒左右. 或者更少.
set @a=1
while @a<=5000
begin
insert into #temppp(tmpNo,tmpName,TmpStatus) values('1000','今天','1')
set @a=@a+1
enddrop table #temppp
我的机器用0.04秒,如果你的机器高级,执行速度更快
要从一个文本文件中或者excel读取5000条左右的记录,记录格式为:
A字段,B字段,C字段 每条记录都是三个字段,以逗号分隔..
现在是读取一条就往数据库对应的这个表里添加一条..所以就循环插入5000次
什么意思??目前是很蠢的方法..
for i:=0 to 5000 do
AddItemRelationDesc(A,B,C); 这样来执行的,5000次
那是因为每次循环插入的时候,字段值不一样啊,所以要用变量传入啊..原生的insert into 更好?
Insert_Lst: TstringList;
begin
Insert_Lst := TStringList.Create;
try
for I := 0 to Count - 1 do //最好每500~1000条做一批
Insert_lst.Add('Insert into tablename (Field1,Field2...) Value(''+StringValue1+''','+IntValue ...')');
Insert_Lst.LineBrek := ';';//对于低版本如果不支持LineBreak的可以在上面的行末尾增加一个分号来解决
ADOCommand.CommandText := Insert_Lst.Text;
ADOCommand.Execute;
finally
Insert_Lst.Free;
end;
end;一个以前写的示例:
const AnsiString SplitEmpty="",Split=";";
DWORD StartTime=GetTickCount();
int Count,iCacheSize=1000;
TStringList *CacheList=new TStringList();
try
{
for(int i=0;i<200000;i++)
{
if(Count)
CacheList->Add(";Insert into tablename (field1,field2,field3[...,fieldn]) values(value1,value2,value3[...,valuen])");
else
CacheList->Add("Insert into tablename (field1,field2,field3[...,fieldn]) values(value1,value2,value3[...,valuen])");
Count++;
if(Count==iCacheSize)
{
ADOCommand->CommandText=CacheList->Text;
CacheList->Clear();
Count=0;
ADOCommand->Execute();
}
}
if(Count>0)
{
ADOCommand->CommandText=CacheList->Text;
ADOCommand->Execute();
}
}
__finally
{
CacheList->Free();
}
DWORD EndTime=GetTickCount();
ShowMessage((int)(EndTime-StartTime));