如何避免重复键异常

时间:2010-06-17 13:26:04

标签: c# sql exception tableadapter

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

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

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

首次运行此循环后,Insert会抛出Duplicate Primary Key found Exception。为了解决这个问题,我已经完成了这个

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不起作用。

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

3 个答案:

答案 0 :(得分:1)

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

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

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

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

答案 1 :(得分: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

然后,代码中的Insert方法可以是ExecuteScalar(),而不是ExecuteNonQuery()。你的代码会以这种方式处理

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

但是,如果那是一个选项,我只会修改表格。

答案 2 :(得分:1)

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

要查看哪些数据存在问题,请在从应用程序运行循环时运行探查器,并查看实际发送的数据。那个shoudl指向哪个记录是重复的。

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