在循环性能中将数据插入db

时间:2010-08-14 12:24:09

标签: c# sql-server ado.net

我正在尝试编写Windows应用程序以从From Fox Pro DB获取数据,并将其插入到Sql Server 2008 db。

我编写代码,但效果很慢。 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();
}

我无法使用批量复制,数据库列的顺序可能在某些源表中有所不同。 我也得到错误:

  

CLR无法过渡   从COM上下文0x54afe8到COM   上下文0x54b158持续60秒。该   拥有目的地的线程   上下文/公寓是最有可能的   或者做一次非抽水等待或者   处理很长时间   没有泵Windows的操作   消息。这种情况一般都有   负面的业绩影响和可能   甚至导致应用程序成为   无响应或内存使用   随着时间的推移不断积累。至   一切都避免这个问题   线程公寓(STA)线程   应该使用抽等待原语   (例如CoWaitForMultipleHandles)和   经常在长时间内发送消息   正在运行。

我该如何解决一系列问题?

1 个答案:

答案 0 :(得分: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.