我有一个数据表,其中可能有1000行左右。我需要逐行遍历数据表,获取列的值,运行查询(Access 2007 DB)并使用结果更新数据表。这是我到目前为止所做的工作:
String FilePath = "c:\\MyDB.accdb";
string QueryString = "SELECT MDDB.NDC, MDDB.NDC_DESC "
+ "FROM MDDB_MASTER AS MDDB WHERE MDDB.NDC = @NDC";
OleDbConnection strAccessConn = new OleDbConnection(string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + FilePath));
strAccessConn.Open();
OleDbDataReader reader = null;
int rowcount = InputTable.Rows.Count; //InputTable is the datatable
int count = 0;
while (count < rowcount)
{
string NDC = InputTable.Rows[count]["NDC"].ToString();
//NDC is a column in InputTable
OleDbCommand cmd = new OleDbCommand(QueryString, strAccessConn);
cmd.Parameters.Add("@NDC", OleDbType.VarChar).Value = NDC;
reader = cmd.ExecuteReader();
while (reader.Read())
{
//update the NDCDESC column with the query result
//the query should only return 1 line
dataSet1.Tables["InputTable"].Rows[count]["NDCDESC"] = reader.GetValue(1).ToString();
}
dataGridView1.Refresh();
count++;
}
strAccessConn.Close();
然而,这似乎非常低效,因为查询需要为数据表中的每一行运行一次。还有更好的方法吗?
答案 0 :(得分:3)
你在想update query。你实际上不必逐个遍历每一行。 SQL是set based language,因此您只需编写一个应该对所有行执行的语句。
这样做:
1)创建&gt;查询设计
2)关闭选择表格的对话框
3)确保你处于sql模式(左上角)
4)粘贴这个:
UPDATE INPUTTABLE
INNER JOIN MDDB_MASTER ON INPUTTABLE.NDC = MDDB_MASTER.NDC
SET INPUTTABLE.NDCDESC = [MDDB_MASTER].[NDC_DESC];
5)切换到设计模式,看看会发生什么。您可能必须更正输入表,我找不到它的名称。我假设他们;他们都在同一个数据库中。
您将看到查询类型现在是更新查询。
您可以通过cmd.ExecuteNonQuery(sql)
运行此文本,整个过程应该非常快。如果不是,你需要其中一个表的索引;
这可以通过在NDC上连接两个表然后将NDC_DESC从MDDB_MASTER复制到输入表来实现。
答案 1 :(得分:1)
您可以使用“IN”子句来构建更大的查询,例如:
string QueryString = "SELECT MDDB.NDC, MDDB.NDC_DESC "
+ "FROM MDDB_MASTER AS MDDB WHERE MDDB.NDC IN (";
int rowcount = InputTable.Rows.Count; //InputTable is the datatable
int count = 0;
while (count < rowcount)
{
string NDC = InputTable.Rows[count]["NDC"].ToString();
QueryString += (count == 0 ? "" : ",") + "'" + NDC + "'";
}
QueryString += ")";
您可以使用StringBuilders对其进行优化,因为这可能是很多字符串,但这对您来说很重要。 :)
然后在单个查询中,您将获得所需的所有NDC描述,并避免执行1000个查询。然后,您将浏览阅读器,在InputTable中查找值并更新它们。当然,在这种情况下,您将多次循环输入InputTable,但它可能是更好的选择。特别是如果yor InputTable可以保存重复的NDC值。
另外,请注意您的代码中有OleDbDataReader泄漏。在处理旧阅读器之前,您会继续将阅读器引用重新分配给新的阅读器实例。与命令相同。您继续实例化一个新命令,但没有正确处理它。
答案 2 :(得分:1)
我错过了关于来自Excel的InputTable的部分。
为了更好的速度,您可以在一个select语句中将MDDB_MASTER中的所有行转换为数据表,而不是在Access中反复执行查询:
SELECT MDDB.NDC, MDDB.NDC_DESC FROM MDDB_MASTER
然后使用DataTable.Select方法过滤右侧行。
mddb_master.Select("NDC = '" + NDC +'")
这将在记忆中完成,并且应该比你现在的所有往返都快得多。特别是在网络上,这些往返行程很昂贵。
,225k行应该只有几MB(大致是JPEG图像),所以这不应该是个问题。