2010-06-17 129 views
0

我正在使用TableAdapter在循环中的表中插入记录。如何避免重复键异常

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

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

第一次运行此循环后,插入抛出重复主键发现异常。为了解决这个问题,我做了这个

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语句的情况下处理它。

+6

避免插入重复的主键。 – 2010-06-17 13:29:29

回答

1

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

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

伪代码示例:在代码中,而不是的ExecuteNonQuery(

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

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

然后,你插入法),是的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 

但是,我只是修改表,如果这是一个选项。

1

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

通常这是通过一个标识列或类似的东西来完成的。 (它看起来像你可能已经在TeamID方面,在这种情况下,你只需要在SQL-MS或VS2010中将其更改为主键)。

编辑:

转到服务器资源管理器:要使用Visual Studio指定一个主键标识列(teamID在你的例子)。导航到相关表格。右键单击“打开表格定义”。点击主键列。滚动属性窗口,直到达到“身份规格”。把它改为“yes”(你可以将增量/种子设置为你想要的值,通常1,1是很好的)。现在,您所要做的就是在表格中插入一个团队名称,并自动生成TeamID。

+0

是的,teamId是主键 – SMUsamaShah 2010-06-17 13:29:44

+1

是否将teamID设置为标识列? (即自我生成,自动标记?) – 2010-06-17 13:31:17

+0

teamId是唯一的,我从xml文件中提取teamId,其中包含每个团队的唯一teamId。 teamId本身是独一无二的 – SMUsamaShah 2010-06-17 13:35:31

1

数据中有明显重复的部分。要么你需要先消除它们,要么使用某种类型的合并语句,如果是新的,则使用isert;如果不是新的,则使用更新。

要查看造成问题的数据,运行分析器,同时从应用程序运行循环并查看实际发送的数据。这句话指出你正在复制哪条记录。

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