excel数据导入到数据库---速度太慢求优化

水向东流时光怎么偷 2011-04-09 05:58:25
我先说一下下面代码的思路,Button1先把excel数据导入到dbgrid中,Button2把dbgird的数据导入到数据库

有4000条数据,需要1分钟,速度太慢了,请各位大虾帮忙看看

如嫌分少,问题完美解决了,我在散100分!
Unit Unit1;
代码
Interface

Uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, ADODB, StdCtrls, Grids, DBGrids, ComObj;

Type
TForm1 = Class(TForm)
DBGrid1: TDBGrid;
Button1: TButton;
Button2: TButton;
ADOConnection1: TADOConnection;
ADOQuery1: TADOQuery;
DataSource1: TDataSource;
OpenDialog1: TOpenDialog;
Procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
PRIVATE
{ Private declarations }
PUBLIC
{ Public declarations }
End;

Var
Form1: TForm1;

Implementation

{$R *.dfm}

Procedure TForm1.Button1Click(Sender: TObject);
Var
ASql, APath: String;
ExcelApp: Variant;
AInt: Integer;
Begin
If OpenDialog1.Execute Then
APath := OpenDialog1.FileName
Else
Exit;

If not FileExists(APath) Then
Begin
ShowMessage('您所选择的文件不存在!');
Exit;
End;
Try
//ADOQuery1.DisableControls;
ExcelApp := CreateOleObject('Excel.Application');
ExcelApp.Workbooks.Open(APath);
ExcelApp.WorkSheets[1].Activate;

ASql := 'select * from stock where 1=2'; //表名 ,也可以在show里面先打开数据集
ADOQuery1.Close; //数据集的 LockType属性 要设为 ltBatchOptimistic
ADOQuery1.SQL.Text := ASql; //才可以批量保存
ADOQuery1.Open;
// DataSource1.DataSet:=nil;

For AInt := 2 To ExcelApp.ActiveSheet.UsedRange.rows.count Do //AInt 起始行数,重哪行开始导入,Aint初始值就是几
Begin
ADOQuery1.Append;
ADOQuery1.FieldByName('st_id').AsString := ExcelApp.Cells[AInt, 1].Value; //Aint是第几行,后面的数字是第几列,
ADOQuery1.FieldByName('st_dcdate').AsDateTime := ExcelApp.Cells[AInt, 2].Value;
ADOQuery1.FieldByName('st_gc').AsString := ExcelApp.Cells[AInt, 3].Value;
ADOQuery1.FieldByName('st_kcd').AsString := ExcelApp.Cells[AInt, 4].Value;
ADOQuery1.FieldByName('st_zt').AsString := ExcelApp.Cells[AInt, 5].Value;
ADOQuery1.FieldByName('st_lx').AsString := ExcelApp.Cells[AInt, 6].Value;
ADOQuery1.FieldByName('st_sx').AsString := ExcelApp.Cells[AInt, 7].Value;
ADOQuery1.FieldByName('st_gys').AsString := ExcelApp.Cells[AInt, 8].Value;
ADOQuery1.FieldByName('st_sku').AsString := ExcelApp.Cells[AInt, 9].Value;
ADOQuery1.FieldByName('st_spmc').AsString := ExcelApp.Cells[AInt, 10].Value;
ADOQuery1.FieldByName('st_pch').AsString := ExcelApp.Cells[AInt, 11].Value;
ADOQuery1.FieldByName('st_tkdate').AsDateTime := ExcelApp.Cells[AInt, 12].Value;
ADOQuery1.FieldByName('st_kw').AsString := ExcelApp.Cells[AInt, 13].Value;
ADOQuery1.FieldByName('st_qty').AsString := ExcelApp.Cells[AInt, 14].Value;
ADOQuery1.FieldByName('st_bzs').AsString := ExcelApp.Cells[AInt, 15].Value;
ADOQuery1.FieldByName('st_tj').AsSingle := ExcelApp.Cells[AInt, 16].Value;
ADOQuery1.FieldByName('st_zl').AsFloat := ExcelApp.Cells[AInt, 17].Value;
ADOQuery1.FieldByName('st_tps').AsFloat := ExcelApp.Cells[AInt, 18].Value;
ADOQuery1.FieldByName('st_mj').AsFloat := ExcelApp.Cells[AInt, 19].Value;
ADOQuery1.FieldByName('st_kcts').AsString := ExcelApp.Cells[AInt, 20].Value;
ADOQuery1.FieldByName('st_bz').AsString := ExcelApp.Cells[AInt, 21].Value;
//因为你的excel是固定格式,所以,这里需要写死;
ADOQuery1.Post;
End;
//ADOQuery1.EnableControls;
Finally
ExcelApp.WorkBooks.Close;
ExcelApp.quit;
ShowMessage('读取库存数据成功 ');
End;
End;

procedure TForm1.Button2Click(Sender: TObject);
begin
try
ADOQuery1.UpdateBatch;
ShowMessage('数据导入成功');
except
ShowMessage('数据库存储错误!');
end;
end;

End.
...全文
825 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
广州佬 2011-04-10
  • 打赏
  • 举报
回复
Delphi6编译、运行通过
广州佬 2011-04-09
  • 打赏
  • 举报
回复
//快速从Excel导入数据:

procedure TForm1.Button1Click(Sender: TObject);//在数据库中自动生成表 qqq
var s:string;
ADOConn:TADOConnection;
aDataSet:TADODataSet;
begin
if OpenDialog1.Execute then
begin
ADOConn:=TADOConnection.Create(self);
ADOConn.LoginPrompt:=false;
ADOConn.ConnectionString:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source='
+OpenDialog1.FileName
+';Extended Properties=Excel 8.0;Persist Security Info=False';
aDataSet:=TADODataSet.Create(self);
aDataSet.Connection:=ADOConn;
ADOConn.OpenSchema(siTables,EmptyParam,EmptyParam,aDataSet);
aDataSet.Last;
s:=aDataSet.Fields.Fields[2].AsString;//获取第一工作表表名
aDataSet.Close;
aDataSet.Free;
ADOConn.Close;
ADOConn.Free;

ADOQuery2.Connection:=ADOConnection1;
ADOQuery2.SQL.Clear;
ADOQuery2.SQL.Append('select * into qqq from OPENROWSET(');//将这个‘qqq’字改为你的数据库中的表名
ADOQuery2.SQL.Append(quotedstr('MICROSOFT.JET.OLEDB.4.0'));
ADOQuery2.SQL.Append(','+quotedstr('Excel 5.0;HDR=YES;Excel 8.0;DATABASE='+OpenDialog1.FileName)+',['+s+'])');
ADOQuery2.ExecSQL;
showmessage('ok');
end;
end;

procedure TForm1.Button3Click(Sender: TObject);//在数据库中已经存在表 qqq
var s:string;
ADOConn:TADOConnection;
aDataSet:TADODataSet;
begin
if OpenDialog1.Execute then
begin
ADOConn:=TADOConnection.Create(self);
ADOConn.LoginPrompt:=false;
ADOConn.ConnectionString:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source='
+OpenDialog1.FileName
+';Extended Properties=Excel 8.0;Persist Security Info=False';
aDataSet:=TADODataSet.Create(self);
aDataSet.Connection:=ADOConn;
ADOConn.OpenSchema(siTables,EmptyParam,EmptyParam,aDataSet);
aDataSet.Last;
s:=aDataSet.Fields.Fields[2].AsString;//获取第一工作表表名
aDataSet.Close;
aDataSet.Free;
ADOConn.Close;
ADOConn.Free;

ADOQuery2.Connection:=ADOConnection1;
ADOQuery2.SQL.Clear;
ADOQuery2.SQL.Append('insert into qqq select * from OPENROWSET(');//将这个‘qqq’字改为你的数据库中的表名
ADOQuery2.SQL.Append(quotedstr('MICROSOFT.JET.OLEDB.4.0'));
ADOQuery2.SQL.Append(','+quotedstr('Excel 5.0;HDR=YES;Excel 8.0;DATABASE='+OpenDialog1.FileName)+',['+s+'])');
ADOQuery2.ExecSQL;
showmessage('ok');
end;
end;
  • 打赏
  • 举报
回复
补充:
1.或者还有其它解决办法
2.大家是怎么解决这类问题的





网管教程 从入门到精通软件篇 ★一。★详细的xp修复控制台命令和用法!!! 放入xp(2000)的光盘,安装时候选R,修复! Windows XP(包括 Windows 2000)的控制台命令是在系统出现一些意外情况下的一种非常有效的诊断和测试以及恢复系统功能的工具。小编的确一直都想把这方面的命令做个总结,这次辛苦老范给我们整理了这份实用的秘笈。   Bootcfg   bootcfg 命令启动配置和故障恢复(对于大多数计算机,即 boot.ini 文件)。   含有下列参数的 bootcfg 命令仅在使用故障恢复控制台时才可用。可在命令提示符下使用带有不同参数的 bootcfg 命令。   用法:   bootcfg /default  设置默认引导项。   bootcfg /add    向引导列表中添加 Windows 安装。   bootcfg /rebuild  重复全部 Windows 安装过程并允许用户选择要添加的内容。   注意:使用 bootcfg /rebuild 之前,应先通过 bootcfg /copy 命令备份 boot.ini 文件。   bootcfg /scan    扫描用于 Windows 安装的所有磁盘并显示结果。   注意:这些结果被静态存储,并用于本次会话。如果在本次会话期间磁盘配置发生变化,为获得更新的扫描,必须先重新启动计算机,然后再次扫描磁盘。   bootcfg /list   列出引导列表中已有的条目。   bootcfg /disableredirect 在启动引导程序中禁用重定向。   bootcfg /redirect [ PortBaudRrate] |[ useBiosSettings]   在启动引导程序中通过指定配置启用重定向。   范例: bootcfg /redirect com1 115200 bootcfg /redirect useBiosSettings   hkdsk   创建并显示磁盘的状态报告。Chkdsk 命令还可列出并纠正磁盘上的错误。   含有下列参数的 chkdsk 命令仅在使用故障恢复控制台时才可用。可在命令提示符下使用带有不同参数的 chkdsk 命令。   vol [drive:] [ chkdsk [drive:] [/p] [/r]   参数  无   如果不带任何参数,chkdsk 将显示当前驱动器中的磁盘状态。 drive: 指定要 chkdsk 检查的驱动器。 /p   即使驱动器不在 chkdsk 的检查范围内,也执行彻底检查。该参数不对驱动器做任何更改。 /r   找到坏扇区并恢复可读取的信息。隐含着 /p 参数。   注意 Chkdsk 命令需要 Autochk.exe 文件。如果不能在启动目录(默认为 %systemroot%System32)中找到该文件,将试着在 Windows 安装 CD 中找到它。如果有多引导系统的计算机,必须保证是在包含 Windows 的驱动器上使用该命令。 Diskpart   创建和删除硬盘驱动器上的分区。diskpart 命令仅在使用故障恢复控制台时才可用。   diskpart [ /add |/delete] [device_name |drive_name |partition_name] [size]   参数 无   如果不带任何参数,diskpart 命令将启动 diskpart 的 Windows 字符模式版本。   /add   创建新的分区。   /delete   删除现有分区。   device_name   要创建或删除分区的设备。设备名称可从 map 命令的输出获得。例如,设备名称:   DeviceHardDisk0   drive_name   以驱动器号表示的待删除分区。仅与 /delete 同时使用。以下是驱动器名称的范例:   D:   partition_name   以分区名称表示的待删除分区。可代替 drive_name 使用。仅与 /delete 同时使用。以下是分区名称的范例:   DeviceHardDisk0Partition1    大小   要创建的分区大小,以兆字节 (MB)表示。仅与 /add 同时使用。   范例   下例将删除分区: diskpart /delete Device HardDisk0 Partition3 diskpart /delete F:   下例将在硬盘上添加一个 20 MB 的分区:   diskpart /add Device HardDisk0 20   Fixboot

2,499

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧