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

发布于 2024-09-14 11:52:44 字数 1332 浏览 1 评论 0原文

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

我写了代码,但是运行速度很慢。行数超过 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)和 在长时间内定期发送消息 运行操作。

我怎样才能解决我的一系列问题?

I'm trying to write Windows app to get data from From Fox Pro DB, and inset it to Sql Server 2008 db.

I wrote code, but it works very slow. rowsCount more than 1 million
My code below:

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();
}

I cant use bulk copy, database columns order may be different in some source tables.
Also I get error:

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.

how can I solve a set of my problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

尴尬癌患者 2024-09-21 11:52:44

我认为有一些方法可以解决您的批量复制问题,我建议您/我们解决这些问题,而不是试图检查为什么缓慢的技术很慢。您说不能使用批量复制的原因是因为某些源表中的数据库列顺序可能不同。我对此的回答是,为什么这很重要?如果您使用 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.

I think there are ways to get around your problems with Bulk Copy and I suggest you/we work through those rather than try to examine why a slow technology is slow. You say the reasons you can't use Bulk Copy are because the database column order may be different in some source tables. My response to that is, why does that matter? If you are using the SqlBulkCopy object, don't you have total control over how the columns in the source tables map to the columns in the destination tables? (Have you tried using the SqlBulkCopy object?) You also say that you can an error message about an unresponsive program. It looks like it's related to COM. I don't see why that would be a problem with Bulk Copy over something that takes even longer to execute. If necessary, you may have to perform Bulk Copy operations in smaller batches (perhaps completely finishing/committing batches before beginning the next?) in order for your program not to "lose control" over its execution. Does this help or provoke any further questions that may lead to an answer?

Edit:
Can you do something like this?

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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文