大批量、多条记录插入如何加快速度(50分)

  • 主题发起人 主题发起人 yubo
  • 开始时间 开始时间
哪为什么我的不行?!
for i := 0 to wzkcz.Count - 1 do
begin
strSql := 'insert into VIEW_WZKCZ_REAL(TZYEAR, TZMONTH, WZZ_ID,';
strSql := strSql + 'WZBM_ID, WZNAME, WZTYPE, WZUNIT, WZCFWZ, KCLB,';
strSql := strSql + ' SBBM, CLBM, ABCTYPE, BGYID,';
strSql := strSql + ' WZDQSL, WZDQZJE, WZPJDJ, WZGC, WZDC, YCKCSL, ';
strSql := strSql + ' YCKCJE, BYSLLJ, BYSLZJELJ, BYLLLJ, BYLLZJELJ, ';
strSql := strSql + ' BYXSLJ, BYXSZJELJ, QCKCSL, QCKCJE, BNSLLJ, ';
strSql := strSql + ' BNSLZJELJ, BNLLLJ, BNLLZJELJ, BNXSLJ, BNXSZJELJ)';
strSql := strSql + ' Values(''' + TZYEAR + ''',''' + TZMONTH + ''',''' + WZZ_ID + ''',''';
strSql := strSql + WZBM_ID + ''',''' + WZNAME + ''',''';
strSql := strSql + WZTYPE + ''',''' + WZUNIT + ''',''' + WZCFWZ + ''',''';
strSql := strSql + KCLB + ''',''' + SBBM + ''',''' + CLBM + ''',''';
strSql := strSql + ABCTYPE + ''',''' + BGYID + ''',';
strSql := strSql + FloatToStr(WZDQSL) + ',' + FloatToStr(WZDQZJE) + ',' + FloatToStr(WZPJDJ) + ',';
strSql := strSql + FloatToStr(WZGC) + ',' + FloatToStr(WZDC) + ',' + FloatToStr(YCKCSL) + ',';
strSql := strSql + FloatToStr(YCKCJE) + ',' + FloatToStr(BYSLLJ) + ',' + FloatToStr(BYSLZJELJ) + ',';
strSql := strSql + FloatToStr(BYLLLJ) + ',' + FloatToStr(BYLLZJELJ) + ',';
strSql := strSql + FloatToStr(BYXSLJ) + ',' + FloatToStr(BYXSZJELJ) + ',' + FloatToStr(QCKCSL) + ',';
strSql := strSql + FloatToStr(QCKCJE) + ',' + FloatToStr(BNSLLJ) + ',';
strSql := strSql + FloatToStr(BNSLZJELJ) + ',' + FloatToStr(BNLLLJ) + ',' + FloatToStr(BNLLZJELJ) + ',';
strSql := strSql + FloatToStr(BNXSLJ) + ',' + FloatToStr(BNXSZJELJ) +')';
WzDataModule.goQuery.SQL.Add(strSql);
WzDataModule.goQuery.SQL.Add('/');//这一句加不加一样
if WzDataModule.goQuery.SQL.Count>50 do
begin
WzDataModule.goQuery.ExecSQL;
WzDataModule.goQuery.SQL.Clear;
end;
end;
if WzDataModule.goQuery.SQL.Count>0 do
begin
WzDataModule.goQuery.ExecSQL;
WzDataModule.goQuery.SQL.Clear;
end;
 
1.肯定不需要SQL.Add('/');
2.你这个SQL单条就可以执行吗?
你把 "if WzDataModule.goQuery.SQL.Count>50 do" 注释掉看看
3.出的什么错误信息?
 
在你的 Query1.execsql 之前 用一下 Query1.prepare,速度会快很多。这个办法我常用。
 
不知tbatch如何,不妨一试
 
to:温柔一刀
单条行 大约需要15--20分钟我现在的程序就这么用
starttransaction,commit快一点3分钟的样子
 
把阀值改小一点,50改为30,25之类。
SQL是tstrings类型,语句太长有时会出问题。
 
设置你的bde也许有帮助
 
To 温柔一刀:
我试过两条都不行
提示SQL语句没有正确结束
你用的什么数据库可否给我一个例子
yubo168@yeah.net
 
To 温柔一刀:
我新建CREATE TABLE TEST1 (
A DOUBLE PRECISION,
B DOUBLE PRECISION
)
SQL语句:
insert into test1(a,b) values(1,2)
insert into test1(a,b) values(1,2)
单条能执行,直接写在TQuery.SQL属性中
InterBase 的提示
'General SQL error.
Token unknown - line 2, char -1
insert'

Oracle 的记不清了意思是'SQL语句没有正确结束'
 
对Query里的sql语句要有正确的分割符来分割,否则你的SQL语句本身就不规范,当然
会出现语句未正常结束的错误,温柔N刀没有把问题说清楚!分割符是分号.在你循环时把分号加进去,使最后在Query的SQL中的语句为下列形式:

insert into .....;
insert into......;
...
 
可以用BatchMove试试
 
to only you
还是不行
'General SQL error.
Token unknown - line 2, char -1
insert'
SQL语句如下
insert into Test1(a,b) Values(9,9);
insert into Test1(a,b) Values(9,9);
 
每个系统的SQL分割符有所不同,你用的什么?interbase?Oracle?
 
to 温柔一刀
InterBase,Oracle我都试过,都不行,关于不同数据库SQL语句分割符,
在哪可以查到,帮助(Delphi 或 数据库)里有吗?

我的程序运行在Oracle8数据库上.
 
我曾经试过该类的操作。
你有没有用过 ADOTable 和ADOQuery, 我用ADOTable是速度都非常快,你可以用ADOTable和ADOQuery试试。
1000条记录5秒
12000条记录嘛就久一点要 4 分钟.
如果是Table和Query试试把CachedUpdate该为false看看,也许会快很多。

 
绝对应该用 存储过程,如果这样速度还慢,应该整理一下你的思路。
提示:有效使用UNION 、SUM、和嵌套过程。
 
对不起,不同系统的分割符我也不知道。
而且我前面说得确实不够准确,
某些数据库系统不支持多条SQL,
interbase似乎就是其中一个。

这种情况下,只能用我说的另一个办法,
即transaction来提高速度。

这次出刀有点偏,抱歉。
 
TQuery似乎一次只能执行一条SQL语句,这是由BDE所限制的,你可以去下载一个
SQLSTMT控件,可以执行多条SQL语句其原理是根据定义的分界符(如SQL Server中
的GO)分解为单条SQL语句执行。
 
to 温柔一刀
在麻烦你一下,你用的什么数据库?Oracle支持多条语句的执行吗?
To Hexi
SQLSTMT 哪可以下载,有源码吗?
 
建议你写存储过程吧
用oracle自己的pl/sql写,
比用delphi在控件里写sql语句要爽多了
 

Similar threads

S
回复
0
查看
835
SUNSTONE的Delphi笔记
S
S
回复
0
查看
765
SUNSTONE的Delphi笔记
S
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部