0

我正在使用 TableAdapter 在循环中的表中插入记录。

foreach(....)
{
  ....
  ....
  teamsTableAdapter.Insert(_teamid, _teamname);
  ....
}

其中 TeamID 是表中的主键,_teamID 插入它。实际上我正在从包含唯一 teamId 的 XML 文件中提取数据

首次运行此循环后,Insert 抛出 Duplicate Primary Key found 异常。为了处理这个,我做了这个

foreach(....)
{
  ....
  ....

  try
  {
     _teamsTableAdapter.Insert(_teamid, _teamname);
  }
  catch (System.Data.SqlClient.SqlException e)
  {
     if (e.Number != 2627)
        MessageBox.Show(e.Message);
  }
  ....
  ....
}

但是使用 try catch 语句代价高昂,如何避免这个异常。我在 VS2010 中工作并且INSERT ... ON DUPLICATE KEY UPDATE不工作。

我想避免 try catch 语句并在不使用 try catch 语句的情况下处理它。

4

3 回答 3

1

您使用的表是否有主键?如果没有,您应该创建一个,因为它可以防止重复记录,并且可能更容易访问程序其他部分的密钥。

通常这是通过身份列或类似的东西来完成的。(看起来您可能已经拥有 TeamID,在这种情况下,您只需将其更改为 SQL-MS 或 VS2010 中的主键)。

编辑:使用 Visual Studio 将主键指定为标识列(在您的示例中为 teamID):

转到服务器资源管理器。导航到相关表。右键单击“打开表定义”。单击主键列。滚动属性窗口,直到到达“身份规范”。将此更改为“是”(您可以将增量/种子设置为您想要的任何值。通常 1,1 很好)。现在,您所要做的就是在表中插入一个 Team Name,然后 TeamID 就会自动生成。

于 2010-06-17T13:29:08.003 回答
1

根据您对其他答案的评论,我建议将 TeamID 从主键更改(如果可能)并将新的 Idx 列设置为主键。然后,您可以在数据库上设置触发器,当插入带有重复 TeamID 的新记录时,将更新原始记录并删除新记录。

如果这不可能,我将修改插入记录的存储过程,以便它首先检查重复的 TeamID,而不是仅仅插入。如果没有重复的 id,记录可以插入,否则它将只是“选择 0”。

伪代码示例:

Declare @Count int
Set @Count = (Select Count(TeamId) From [Table] where TeamId = @TeamId)

If(@Count > 0)
  Begin
    Select 0
  End
Else
 --Insert Logic Here

然后,您在代码中的插入方法可以不是 ExecuteNonQuery(),而是 ExecuteScalar()。你的代码会这样处理

If(_teams.TableAdapter.Insert(_teamId, _teamName) == 0)
  {
    _teams.TableAdapter.Update(_teamId, _teamName)
  }

或者,如果您只想在 SQL 中处理这一切(因此您的 C# 代码不必更改),您可以执行以下操作:

Declare @Count int
Set @Count = Select Count(TeamId) from [Table] Where TeamId = @TeamId

If(@Count > 0)
  Begin
    //Update Logic
  End
Else
  Begin
    //Insert Logic
  End

但是,如果可以的话,我会再次修改表格。

于 2010-06-17T13:58:09.883 回答
1

您的数据中有明显的重复项。您需要先消除它们,或者使用某种类型的合并语句来执行新的插入语句或更新(如果不是新的语句)。

要查看导致问题的数据,请在从应用程序运行循环时运行分析器,并查看实际发送的数据。那应该指向您复制的记录。

如果这是一个大文件,批量插入(在清理 dups 之后)将比逐行处理更快。

于 2010-06-17T13:59:29.663 回答