2010-08-14 61 views
1

我想写Windows应用程序从Fox Pro数据库获取数据,并插入到Sql Server 2008数据库。插入数据到数据库循环性能

我写了代码,但它工作得很慢。 rowsCount超过100万级 我下面的代码:

OleDbConnection cn = new OleDbConnection(foxProConnectionString); 
SqlConnection cSql = new SqlConnection(sqlServerConnectionString); 
cSql.Open(); 

OleDbCommand ocmd = new OleDbCommand("Select * from " + table, cn); 
OleDbDataAdapter sda = new OleDbDataAdapter(ocmd); 
DataTable dt = new DataTable(); 
sda.Fill(dt); 
SqlCommand mySqlcmd = new SqlCommand(); 
mySqlcmd.Connection = cSql; 

for (int i = 0; i < dt.Rows.Count; i++) 
{ 
    mySqlcmd.CommandText = "INSERT INTO sqlTable (column1, column2, column3) VALUES ("+dt.Rows[i][dt.Columns.IndexOf("column1")] + ",'" 
              + DoOper1(dt.Rows[i]dt.Columns.IndexOf("column2")]) + "','" 
              + dt.Rows[i][dt.Columns.IndexOf("column3")] + "')"; 

    mySqlcmd.ExecuteNonQuery(); 
} 

我不能使用批量复制,数据库中的列顺序可能会在某些源表不同。 此外,我得到错误:

The CLR has been unable to transition from COM context 0x54afe8 to COM context 0x54b158 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.

我怎么能解决一组我的问题吗?

+0

速度有多慢?例如,运行sql更新我们2500万记录用户表中的密码列大约需要12个小时。 – 2010-08-14 12:28:38

+0

删除该表中的所有索引和约束,并在数据加载后将其还原。 – Rup 2010-08-14 12:30:31

+0

从foxPro操作中获取数据并插入约100万行约需3分钟。 – loviji 2010-08-14 12:31:54

回答

2

我认为有办法解决大容量复制的问题,我建议您/我们通过这些解决方案来解决问题,而不是试图研究缓慢技术为什么会很慢。你说你不能使用批量复制的原因是因为在某些源表中数据库的列顺序可能不同。我对此的回应是,为什么这很重要?如果您使用的是SqlBulkCopy对象,那么您是否完全控制源表中的列映射到目标表中的列的方式? (您是否尝试过使用SqlBulkCopy对象?)您也可以说您可以收到有关无响应程序的错误消息。看起来它和COM有关。我不明白为什么这对于批量复制而言是一个需要更长时间才能执行的问题。如果有必要,您可能必须以较小的批次执行批量复制操作(也许在开始下一步之前完全完成/提交批次?),以便程序不会在其执行过程中“失去控制”。这是否有助于或引发任何可能导致答案的进一步问题?

编辑: 你能做这样的事吗?

System.Data.SqlClient.SqlBulkCopy bc = new System.Data.SqlClient.SqlBulkCopy("..."); 

// Begin a loop to process managable-size batches of source data. 

using (System.Data.DataTable dtTarget = new System.Data.DataTable("sqlTable")) 
{ 

    // Populate dtTarget with the data as it should appear 
    // on the SQL Server side. 
    // If the mapping is simple, you may be able to use 
    // bc.ColumnMappings instead of manually re-mapping. 

    bc.DestinationTableName = "sqlTable"; 
    bc.WriteToServer(dtTarget); 
} 

// End loop. 
+0

我用sqlBulkCopy,可能是我不知道SqlBulkCopy的全部功能。例如,我从源表读取数据。那么我可以用一些列数据做一些操作,然后把它写入到sql server中,在那里存在带有数据的表?如果是的话,我该怎么做? – loviji 2010-08-14 12:49:39

+0

您可以完全控制将列和行提交给SQL服务器的方式,因为您可以使用其中的任何数据创建DataTable。我已将示例代码添加到我的答案中。使用这样的代码有什么问题吗? – BlueMonkMN 2010-08-14 13:12:01