使用Powerbuilder将数据从DataWindow / DataStore复制到SQL Server表的最快方法是什么

时间:2014-07-10 18:27:02

标签: sql-server powerbuilder datastore datawindow

我们有一个数据存储区( powerbuilder 数据窗口的双胞胎姐妹),其中包含 40.000行,这需要超过 30分钟插入 Microsoft SQL Server 表。

目前,我正在使用一个脚本生成器,它为每一行生成sql表定义和insert命令。最后,完整的脚本到sql server执行。

我已经发现脚本生成过程消耗的内容超过整个任务的 97%

你能帮我找一个更有效的方法将我的客户端数据复制到sql server表吗?

编辑1 (在NoazDad的评论之后):

在回答之前,请记住:

  • 表格结构是动态的;
  • 我试图避免使用datastore.Update()方法;

4 个答案:

答案 0 :(得分:3)

不确定它会更快但您可以在制表符分隔文件中保存数据存储区中的数据,然后通过Sql执行BULK INSERT。像

这样的东西

BULK 插入CSVTest FROM' c:\ csvtest.txt' WITH ( FIELDTERMINATOR =' \ t', ROWTERMINATOR =' \ n' ) GO

您可以尝试通过ds.object.datawindow.data语法将数据存储区内容保存到字符串变量中,然后将其保存到文件中,然后执行SQL。

答案 1 :(得分:2)

我读这个的方式,你说的是,在用户按下“GO”并启动脚本之前,数据插入的表甚至不存在于模式中?然后创建创建表的嵌入式SQL语句,并在循环中逐行插入行?

那是......好吧,我只想说我不会这样做。

你不知道架构会提前出现什么样吗?如果这样做,则根据该表绘制数据存储区,并使用ds_1.Update()生成INSERT语句。使用数据窗口可以获得最佳效果。

如果那是不可能的,并且您必须使用嵌入式SQL,那么至少每1000行左右执行一次COMMIT。否则,SQLServer正在针对表构建UNDO日志,以防出现问题并且必须回滚它们。

答案 2 :(得分:1)

其他想法......

  • 在更新的表(如果可能)更新表时禁用触发器
  • 使用PB Pipeline对象,它具有提交设置 - 可能更快但不多。
  • 最好的主意。在服务器端做一些事情。我尝试为您的40K插入创建SQL语句,并调用存储过程发送所有40k插入/更新语句,并让存储过程处理插入/更新。
  • 创建一个包含几列的虚拟表,一个是长文本,使用上一个想法中提到的SQL语句块更新它,并有一个分隔和执行sql语句的进程。
  • 上面的一些变体,但使用Matt提到的散装插入物。批量插入是插入多行的最快方法。
  • 也许尝试使用自动提交,这样你只能在最后提交,或者已经提到的每10k行。
  • PB在事务对象(连接)中有一个异步选项,也许您可​​以让更新在后台运行并让用户继续。这不适用于所有数据库,可能无法在您的情况下工作。我没有太多运气使用异步选项。

你的进程如此慢的原因是PB会分别更新,所以你不断地访问网络和数据库。更新表上可能存在触发器,这些触发器也受到了重创。在服务器上砰击它们可以消除网络延迟并且速度更快。使用批量加载速度更快,因为它不会运行触发器并消除了大量的数据库管理开销。

扩展将SQL语句发送到过程的想法,您可以通过执行dw_1.saveas(SQL!)(语法不正确)并一次性将其发送到服务器来非常轻松地创建sql。让服务器解析它并运行SQL。

通过程序将类似的内容发送到服务器,它应该快速更新,因为它只有一个声明:

Update TABLE set (col1, col2) values ('a', 'b')|Update TABLE set (col1, col2) values ('a', 'b')|Update TABLE set (col1, col2) values ('a', 'b')

在程序中:

解析sql语句,然后运行它们。容易腻。

答案 3 :(得分:1)

虽然马特的答案可能是最好的,但我有另一种选择。 (选项很好,对吗?)

我不确定你为什么要避开datastore.Update()方法。我假设它是因为更新时架构不存在。如果这是唯一的原因,它仍然可以使用,因此消除了40,000个字符串操作实例以生成有效的SQL。

为此,您首先要创建表格。然后,您将使用datastore.SyntaxFromSQL()来创建绑定到表的数据存储。可能需要一些Modify()语句才能使数据存储更新。然后,您将数据从原始数据存储区移动到可更新的绑定数据存储区。 (查看RowsMo​​ve()或点表示法。)之后,Update()语句生成所有SQL,而不会产生字符串解析和循环的开销。