当我尝试执行超过 1 个查询时,循环在 OleDb 中插入数据中断
Posted
技术标签:
【中文标题】当我尝试执行超过 1 个查询时,循环在 OleDb 中插入数据中断【英文标题】:Loop to insert data in OleDb breaks when I try to execute more than 1 query 【发布时间】:2015-05-14 14:19:43 【问题描述】:我正在开发一个带有 Access 2002 数据库 (.mdb) 和 OleDb 的小型离线 C# 应用程序。
我有 2 个表需要同时插入数据,其中一个持有另一个的外键。因此,为了简化,假设一个表有 2 个属性:“idTable1”(自动增量整数)和“数字”,另一个有 2 个属性:“idTable2”(自动增量整数)和“fkTable1”(包含一个与表 1 中的“idTable1”匹配的整数值。
foreach 循环遍历集合并将每个元素插入 Table1 中。然后想法是在Table1上使用SELECT @@Identity
查询来获取最后插入的记录的自增id字段,并将其作为外键插入到Table2中。
我只是在尝试插入外键之前尝试第一部分:遍历集合,将每个项目插入 Table1 并获取最后插入记录的 idTable1。但是每当我尝试执行 SELECT @@Identity
时,我的数据库中只会得到 1 条记录,即使循环正确地遍历了所有集合项。
我的代码如下所示:
string queryInsertTable1 = "INSERT INTO Table1 (numero) VALUES (?)";
string queryGetLastId = "Select @@Identity";
using (OleDbConnection dbConnection = new OleDbConnection(strDeConexion))
using (OleDbCommand commandStatement = new OleDbCommand(queryInsertTable1, dbConnection))
dbConnection.Open();
foreach (int c in Collection)
commandStatement.Parameters.AddWithValue("", c);
commandStatement.ExecuteNonQuery();
commandStatement.CommandText = queryGetLastId;
LastInsertedId = (int)commandStatement.ExecuteScalar();
如果我注释掉最后 3 行:
commandStatement.CommandText = queryGetLastId;
LastInsertedId = (int)commandStatement.ExecuteScalar();
然后Collection 中的所有记录都正确插入到BD 中。但是一旦我取消注释这些,我只插入了 1 条记录,而存储在“c”中的值是集合中的最后一个元素(所以循环工作正常)。
我还尝试在 commandStatement.ExecuteNonQuery()
句子之后立即调用 commandStatement.Parameters.Clear()
,但这没有区别(不应该,但我仍然尝试过)。
我不想通过使用事务等使事情变得复杂,如果可以避免的话,因为这是一个非常简单的单机离线小型应用程序。因此,如果有人知道我可以做些什么来使该代码正常工作,我将非常感激:)
【问题讨论】:
【参考方案1】:这里:commandStatement.CommandText = queryGetLastId;
您实际上将命令从插入更改为选择身份。
因此,在下一次迭代中,它不会插入任何内容,而是再次选择标识,这就是为什么您只将一条记录插入 DB。
我认为最好有两个单独的命令用于插入和选择身份。
另请注意 - 您尝试在每次迭代时将新参数添加到 commandStatement
中,因此在迭代时,例如 N 它将是 N 个参数。在添加新参数之前清除参数,或者在循环之外添加参数并在循环中仅更改其值。
using (OleDbConnection dbConnection = new OleDbConnection(strDeConexion))
using (OleDbCommand commandStatement = new OleDbCommand(queryInsertTable1, dbConnection))
using (OleDbCommand commandIdentity = new OleDbCommand(queryGetLastId , dbConnection))
commandStatement.Parameters.Add(new OleDbParameter());
dbConnection.Open();
foreach (int c in Collection)
commandStatement.Parameters[0].Value = c;
commandStatement.ExecuteNonQuery();
LastInsertedId = (int)commandIdentity.ExecuteScalar();
【讨论】:
在foreach
的开头加上commandStatement.CommandText = queryInsertTable1
怎么样?
@MikeDebela 好吧,这是可能的。但我仍然认为有两个单独的命令更好。否则,您需要重新分配来回参数、命令文本等 - 这会使代码的可读性大大降低。
该死!我知道这一定很愚蠢 :P 太多的编程和太少的睡眠!谢谢!!【参考方案2】:
一旦您更改了命令文本,第一个查询就会从它那里消失,因此它不会再次向第一个表插入任何数据。重新评估并尝试
【讨论】:
以上是关于当我尝试执行超过 1 个查询时,循环在 OleDb 中插入数据中断的主要内容,如果未能解决你的问题,请参考以下文章
Laravel Eloquent 方法 updateOrCreate 更新时超过执行时间