我目前正在使用OleDBCommand.ExecuteNonQuery(重复调用),一次从源DataTable向dbase文件(* .dbf)中插入多达350,000行。我正在重用OleDbCommand对象和OleDbParameters来设置每次调用insert语句时要插入的值。插入350,000行目前占用我的程序约45分钟。
有更有效的方法吗?是否存在与Dbase(* .dbf)文件中的SQL Server中使用的批量插入选项类似的内容?
答案 0 :(得分:2)
通过将OleDB驱动程序从Jet更改为vfpoledb来解决此问题。这将总时间从40分钟缩短到8分钟。
vfpoledb驱动程序和合并模块是从下面的链接下载的
http://www.microsoft.com/downloads/en/details.aspx?FamilyID=e1a87d8f-2d58-491f-a0fa-95a3289c5fd4
感谢您的帮助。
答案 1 :(得分:1)
如果它是给定表的.dbf和.cdx文件扩展名,它可能是一个Visual FoxPro表而不是特别“dBase”。
如果是这种情况,VFP允许“附加自”命令,看起来像这样......
使用(yourTable) 追加来自SomeFile.txt类型的csv
然而,其他导入文件格式也被接受,如XLS,DELIMITED和其他。
如果是这样,VFP还允许使用ExecScript()命令,您可以在其中构建表示要执行的命令的字符串,然后像正常PRG一样运行它们。并非VFP命令库中的所有内容都可用,而是满足您的需求。您需要使用VFP OleDb提供程序,建立您正在进行的连接。然后,构建一个类似......的脚本。
String script = "[USE YourTable SHARED] +chr(13)+chr(10)+ "
+ "[APPEND FROM OtherTextSource TYPE CSV]";
然后,发出你的
YourConnection.ExecuteNonQuery( "ExecScript( " + script + " ) " );
如果传入源的结构与预期表的结构不同,您还可以创建一个临时表(光标在VFP中),列的顺序与输入源匹配,但具有相同的列名和数据类型作为它们将被拉入的FINAL表,然后使用它作为基础附加到最终表... VFP中的游标是自清理的...即:它们是临时文件,在关闭时立即擦除,并关闭连接将释放它们......比如
String script = "[create cursor C_SomeTempArea( FinalCol1 c(20), "
+ "FinalCol7 int, AnotherCol c(5) )] +chr(13)+chr(10)+ "
+ "[APPEND FROM OtherTextSource TYPE CSV] +chr(13)+chr(10)+ "
+ "[SELECT 0] +chr(13)+chr(10)+ "
+ "[USE YourFinalTable] +chr(13)+chr(10)+ "
+ "[Append from C_SomeTempArea]"
然后,发出你的
YourConnection.ExecuteNonQuery( "ExecScript( " + script + " ) " );
编辑 - 来自反馈
由于它基于DBASE,我会考虑仍然下载VFP OleDb管理器,使用上面的连接,但不是在最后使用你的表并附加到它,只更改结束部分。 ..
删除
+ "[USE YourFinalTable] +chr(13)+chr(10)+ "
+ "[Append from C_SomeTempArea]"
并输入int
+ "[COPY TO TEMPImport TYPE FOXPLUS]"
要键入FOXPLUS的副本会将其放入磁盘上的物理表,DBASE将通过IT OleDb Provider识别该表。然后,回到你的dbase的连接,我会做一个
insert into (YourTable) select * from TempImport
是的,它涉及一个新的OleDb提供商,但VFP SCREAMS在进行此类进口时表现不会出汗......
答案 2 :(得分:1)
根据您的其他反馈,SQL Server具有批量上传功能。
我会创建一个存储过程,该过程需要您尝试上传的文件的名称并在那里完成所有操作。以我描述的与Foxpro类似的方式,我将在SQL中创建一个临时表(如果需要更快的预填充数据),该表与要导入的列匹配,然后导入到该表中。一旦进入临时结构,您就可以对所需的数据进行清理。准备好后,然后从临时导入表中选择插入主表。