// conn is read from handydrive
//conn2 read from C:\
此代码用于将新记录写入C:\中的DB,首先检查是否存在。 我的问题对于很多记录来说太慢了。以及如何提高它... ...
SqlCeCommand cmd1 = new SqlCeCommand("Select * from bill_discount ", conn);
SqlCeDataReader dr1 = cmd1.ExecuteReader();
while (dr1.Read() != false)
{
SqlCeCommand cmd4 = new SqlCeCommand("Select * from bill_discount where bill_no='" + dr1.GetInt32(0) + "' AND bill_shopdc='" + dr1.GetString(2) + "' ", conn2);
SqlCeDataReader dr4 = cmd4.ExecuteReader();
if (dr4.Read() == false)
{
SqlCeCommand cmd2 = new SqlCeCommand("INSERT INTO bill_discount (bill_no,bill_value,bill_shopdc) VALUES ('" + dr1.GetInt32(0) + "','" + dr1.GetDouble(1) + "','" + dr1.GetString(2) + "') ", conn2);
// SqlCeDataReader dr2 = cmd2.ExecuteReader();
cmd2.ExecuteNonQuery();
}
}
//-------------------------------------------------------------------
答案 0 :(得分:3)
我会看一下SqlBulkCopy Class:
让您有效地批量加载SQL 服务器表包含来自另一个的数据 源。
BTW :在上面的代码中,选择整个bill_discount
表并不是一个好主意,特别是如果表格很大。
[此外,您似乎可以执行单个TSQL语句,而不是循环遍历每一行并向数据库进行往返。]
此示例应该有所帮助:SqlBulkCopy - Copy Table Data Between SQL Servers at High Speeds - ADO.NET 2.0 New Feature
答案 1 :(得分:1)
让我们从使代码更具可读性开始。结果如下:
SqlCeCommand getAllBills = new SqlCeCommand("select * from bill_discount", primaryConnection);
SqlCeDataReader allBillsReader = getAllBills.ExecuteReader();
while (allBillsReader.Read())
{
SqlCeCommand getBill = new SqlCeCommand("select * from bill_discount where bill_no = '" + allBillsReader.GetInt32(0) + "' and bill_shopdc = '" + allBillsReader.GetString(2) + "' ", secondaryConnection);
SqlCeDataReader billReader = getBill.ExecuteReader();
if (!billReader.Read())
{
SqlCeCommand addMissingBill = new SqlCeCommand("insert into bill_discount (bill_no, bill_value, bill_shopdc) values ('" + allBillsReader.GetInt32(0) + "', '" + allBillsReader.GetDouble(1) + "', '" + allBillsReader.GetString(2) + "')", secondaryConnection);
addMissingBill.ExecuteNonQuery();
}
}
必须处置一次性物品。我们来做吧。
我们也删除SQL注入。
最后,让我们优化第二个查询:如果您只想检查数据库中是否存在该值,则无需选择某些内容并执行阅读器。
using (SqlCeCommand getAllBills = new SqlCeCommand("select bill_no, bill_value, bill_shopdc from [bill_discount]", primaryConnection))
{
using (SqlCeDataReader allBillsReader = getAllBills.ExecuteReader())
{
while (allBillsReader.Read())
{
using (SqlCeCommand getBill = new SqlCeCommand("if exists(select * from [bill_discount] where [bill_no] = @billNumber and bill_shopdc = @billShop) select 1 else select 0", secondaryConnection))
{
getBill.Parameters.AddWithValue("@billNumber", allBillsReader["bill_no"]);
getBill.Parameters.AddWithValue("@billShop", allBillsReader["bill_shopdc"]);
bool billExists = Convert.ToBoolean(getBill.ExecuteScalar());
if (!billExists)
{
using (SqlCeCommand addMissingBill = new SqlCeCommand("insert into [bill_discount] ([bill_no], [bill_value], [bill_shopdc]) values (@billNumber, @billValue, @billShop)", secondaryConnection))
{
addMissingBill.Parameters.AddWithValue("@billNumber", allBillsReader["bill_no"]);
addMissingBill.Parameters.AddWithValue("@billValue", allBillsReader["bill_value"]);
addMissingBill.Parameters.AddWithValue("@billShop", allBillsReader["bill_shopdc"]);
int countAffectedRows = addMissingBill.ExecuteNonQuery();
Debug.Assert(countAffectedRows == 1, "The data was not inserted.");
}
}
}
}
}
}
所以我们在这里。
现在,它仍然是一种低性能解决方案。为了更有效,您可能希望在带有连接的单个SQL查询中执行相同的操作。由于两个表可能位于不同的服务器上,因此您可以查看链接服务器:一种功能,可以对来自多个服务器的多个表执行单个查询。
答案 2 :(得分:1)
我看到你正在使用SqlCe,它在插入批量数据时有许多限制。主要限制是实际的SqlCe引擎。但是,您可以通过使用直接表插入来绕过它:
using (var command = connection.CreateCommand())
{
command.Transaction = transaction;
command.CommandType = CommandType.TableDirect;
command.CommandText = TABLE_NAME_IN_SQL;
using (var rs = command.ExecuteResultSet(ResultSetOptions.Updatable))
{
var rec = rs.CreateRecord();
rec.SetInt32(0, value0); // the index represents the column numbering
rec.SetString(1, value1);
rec.SetInt32(2, value2);
rs.Insert(rec);
}
}