我正在Excel VBA中制作一些东西,我需要从Excel工作表中读取大约850行或更多行,并在oracle 11g的现有表中更新它们。幸运的是,我只感兴趣的是两列。
我目前正在做的唯一方法就是在Excel中循环使用Range,并为数组中的每个字段创建一个UPDATE myTable SET Temp = Array(i, 2) WHERE id = Array(i,1)
。
现在......我非常清楚这不是快速的,也不是优雅的,这就是为什么我正在寻找优化这种东西的技巧和窍门。
我非常感谢所提供的每一个提示。
=== UPDATE ===
通过制作临时表来测试Kacpers建议后,结果是当使用我感兴趣的2列(大约850行)的excel时,大约需要2分钟读取数据并使用{{{{{{{ 1}}方法,850插入。
另一个表和excel文件有大约970行和3列,而过滤掉我写了大约700行,stll使用大约一分钟完成。
最后一部分是与现有表结合,而此实现之前的过程大约需要35秒,现在需要45-55秒。
这似乎仍然是一种非常缓慢的方法。特别是插入部分 就像我在评论中所说的那样,我无法访问服务器存储系统,因此无法上传或制作CSV来导入数据。
仍然非常感谢我可以用来优化程序的任何提示或提示。
答案 0 :(得分:1)
首先请将您的Excel导入到表或根据xls文件中的csv数据创建外部表。假设您使用列c1,c2
将数据导入到表t1然后你可以执行合并操作:
merge into myTable mt
using t1
on (mt.id = t1.c1)
when matched then update set
Temp = c2;
如果你需要插入myTable中不存在的行,你可以另外放when not matched then insert
;
答案 1 :(得分:1)
您应该使用带有绑定变量的预处理语句(未经测试):
Set cmd = CreateObject("ADODB.Command")
Set cmd.ActiveConnection = con ' your "ADODB.Connection" object
cmd.CommandType = adCmdText
cmd.CommandText = "UPDATE myTable SET Temp = ? WHERE id = ?"
cmd.Parameters.Append cmd.CreateParameter("newVal", adVarChar, adParamInput, 10)
cmd.Parameters.Append cmd.CreateParameter("id", adBigInt, adParamInput)
con.BeginTrans
For i = 1 To 850
cmd.Parameters("newVal").Value = Array(i, 2)
cmd.Parameters("id").Value = Array(i, 1)
cmd.Execute
Next
con.CommitTrans
重要提示:cmd.Parameters.Append
必须在循环外只进行一次。否则你将无法获得任何收益。
很可能它不会像Direct-Path INSERT那样快(例如外部表),但性能应该足够。
答案 2 :(得分:0)
好的,所以我使用了Kacper建议的一半解决方案,这意味着我引入了一个临时表,我首先使用~850 INSERT填充了以下内容:
INSERT ALL INSERT ... END
但解决方案需要大约1-2分钟才能执行。
另一个主题建议我"连接"将我的数据转换为单个插入命令并仅执行一次 这似乎是最有效的方法,所以我的插入目前看起来像:
INSERT INTO myTempTable (id, temp) SELECT 'data1', 'data2' from dual
UNION ALL SELECT 'data3', 'data4' from dual
UNION ALL SELECT 'data5', 'data6' from dual
...
仅花费大约一秒时间执行所有850次插入,并通过平均加入仅约5秒来延长myTable
的更新。
感谢大家参与,并提供了您提供的有用提示!