如何把内存表的数据批量保存到另一个数据库

诸葛不亮2909 2018-12-04 10:08:02
为了提高网络数据库的使用效率,我在客户端本地建立了临时的内存表,用户在本地编辑完数据后, ,如何用代码一次性、批量的保存到网上已知的另一个数据库表中? 而不是逐条记录生成SQL 的 insert 语句来执行。因为这样效率太低,如果数据量大的话,那完全不可行.

我用的是Delphi ,请各位大神赐教, 多谢!
...全文
317 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
诸葛不亮2909 2018-12-06
  • 打赏
  • 举报
回复
谢谢,用事务基本搞定了,效率还是不错的。应该是没有 Clear 那个SQL文本。多谢两位!!
doloopcn 2018-12-05
  • 打赏
  • 举报
回复
建议1:开启事务。就是Connection.BeginTrans,Connection.CommitTrans。这个会触发服务器分配资源协调,速度应该可以了。

建议2:使用SQL SERVER的默认导入功能。如MS SQL SERVER,它有相关的指令和存储过程,可以用代码导入你的数据(前提是,它支持你的数据的格式)
lyhoo163 2018-12-05
  • 打赏
  • 举报
回复
应该二个方面入手,一是减少上传量,特别是排除未变动的数据,这可以使用cliendataset控件,作为内存表,见可以排除未编辑的数据行。二是提高sql语言的效率,可以整合一条语句上传百条数据行的模式。
BlueStorm 2018-12-05
  • 打赏
  • 举报
回复
用子线程做insert,同时用主线程生成后面的insert语句....
BlueStorm 2018-12-05
  • 打赏
  • 举报
回复
如果是sql server的话,可以用一个Insert语句插入多行(例如1000行)的数据方法, 如下面的语句所示: insert into tblname values (v1a, v1b, v1c), (v2a, v2b, v2c), (v3a, v3b, v3c).... 用这种方法,就算你插入1百万条记录,也就是1000个insert语句而已。 如果想更快的话,可以用sql server bcp api来进行导入
BlueStorm 2018-12-05
  • 打赏
  • 举报
回复
如果你的delphi版本低于Delphi xe2, uses列表中Winapi.Windows要改为Windows、System.Classes要改为Classes,其余类推。
BlueStorm 2018-12-05
  • 打赏
  • 举报
回复
另外,可以用sdac代替ado试试。sdac在盒子ftp有,用起来很简单。
BlueStorm 2018-12-05
  • 打赏
  • 举报
回复
内存的问题,看看是不是少了下面一句: Query1.SQL.Clear;
doloopcn 2018-12-05
  • 打赏
  • 举报
回复
引用 5 楼 qq_38118026 的回复:
我用的是SQLServer2005, 无论在Delphi 还是在 查询分析器里, 按下面的插入语法,系统提示错误的。

create table mytest ( shopid char(20), name char(20))


INSERT INTO mytest (shopid,name )VALUES ('A00C','A00F'),('A00G','A00I'),('A00J','A00T')
或者下面
INSERT INTO mytest VALUES ('A00C','A00F'),('A00G','A00I'),('A00J','A00T')

如图


######又是一个中文字符当英文字符用的案例#############
######下面一句的逗号是中文的",",而不是英文的","#######
VALUES ('A00C','A00F')

##############################################
诸葛不亮2909 2018-12-05
  • 打赏
  • 举报
回复
我用ADO的连接,每批500条 分批提交确实是可以明显提高效率的,几千条是没有问题的,但当提交的数据约2万+后,就会提示内存不足,然后就断开连接了。@BlueStorm ,我看到您有一篇 BCP API 的贴子,我拿来学习,但初始编译,就提示如图内容。
BlueStorm 2018-12-05
  • 打赏
  • 举报
回复

procedure TForm1.Button1Click(Sender: TObject);
begin
  with Query1 do
  begin
    SQL.Add('SET NOCOUNT ON');
    SQL.Add('BEGIN TRAN');
    SQL.Add('INSERT INTO TestDB..test VALUES (1, ''aaa'', 18)');
    SQL.Add('INSERT INTO TestDB..test VALUES (2, ''bbb'', 17)');
    SQL.Add('INSERT INTO TestDB..test VALUES (3, ''ccc'', 16)');
    SQL.Add('COMMIT');
    SQL.Add('SET NOCOUNT OFF');
    ExecSQL;
  end;
end;
BlueStorm 2018-12-05
  • 打赏
  • 举报
回复
可以试一下多条Insert语句一起发出去 insert前运行Connection.BeginTrans, insert后运行Connection.CommitTrans
诸葛不亮2909 2018-12-05
  • 打赏
  • 举报
回复
我用的是SQLServer2005, 无论在Delphi 还是在 查询分析器里, 按下面的插入语法,系统提示错误的。

create table mytest ( shopid char(20), name char(20))


INSERT INTO mytest (shopid,name )VALUES ('A00C','A00F'),('A00G','A00I'),('A00J','A00T')
或者下面
INSERT INTO mytest VALUES ('A00C','A00F'),('A00G','A00I'),('A00J','A00T')

如图
BlueStorm 2018-12-05
  • 打赏
  • 举报
回复
开始导入的时候,记得要设置一下: MemTable.DisableControl; 否则界面的跳动会严重影响导入的速度

2,497

社区成员

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

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