如何避免重复键异常

发布于 2024-09-06 04:43:51 字数 689 浏览 4 评论 0原文

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

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

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

第一次运行此循环后,插入会抛出重复主键发现异常。为了处理这个问题,我已经这样做了,

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

I am using TableAdapter to insert records in table within a loop.

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

Where TeamID is the primary key in the table and _teamID inserts it. Actually i am extracting data from XML file which contains unique teamId

After first run of this loop, Insert throws Duplicate Primary Key found Exception. To handle this, i have done this

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

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

But using try catch statement is costly, how to avoid this exception. I am working in VS2010 and INSERT ... ON DUPLICATE KEY UPDATE does not work.

I want to avoid try catch statements and handle it without the use of try catch statements.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

深白境迁sunset 2024-09-13 04:43:51

根据您对其他答案的评论,我建议更改 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

然后,代码中的插入方法可以是 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

但是,再一次,我只需修改表,如果这是一个选择。

Based on your comments to other answers, I would suggest that TeamID be changed from the primary key (if possible) and a new Idx column set up as the primary key. You can then set a trigger on your DB that, when a new record is inserted with a duplicate TeamID will update the original record and delete the new one.

If that is not possible, I would modify the stored procedure which is inserting the record so that, instead of just inserting, it first checks for a duplicate TeamID. If there isn't a duplicate id, the record can insert, Else it will just 'Select 0.'

pseudo-code example:

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

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

Then, your Insert Method in code can, instead of being ExecuteNonQuery(), be ExecuteScalar(). Your code would handle that this way

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

Alternatively, if you just wanted to handle it all in SQL (so your C# code doesn't have to change) you could do something like this:

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

But, again, I'd just modify the table if that's an option.

闻呓 2024-09-13 04:43:51

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

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

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

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

Does the table you're using have a primary key? If not, you should create one as it will prevent duplicate records, and might make it easier to access keys for other parts of your program.

Usually this is done with an Identity Column, or something similar. (Which it looks like you might already have in terms of TeamID, in which case you only need to change it to primary key in either SQL-MS or VS2010).

Edit: To designate a primary key as an identity column (teamID in your example) using Visual Studio:

Go to the server explorer. Navigate to the relevant table. Right-click "Open Table Definition". Click on the primary key column. Scroll the properties window until you reach "identity specification". Change this to "yes" (you can set the increment / seed to whatever you wish. Usually 1,1 is fine). Now, all you have to do is insert a Team Name into the table, and the TeamID is automatically generated.

千年*琉璃梦 2024-09-13 04:43:51

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

要查看导致问题的数据,请在从应用程序运行循环时运行探查器,并查看实际发送的语句。这应该指出哪些记录是重复的。

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

There are clearly duplicates in your data. Either you need to eliminate them first or use some type of merge statment to do an isert if new or an update if not new.

To see what data is casueing the problem, run profiler while you run the loop from your application and see waht statments are actually being sent. That shoudl point you towards which record(s) are duplicated.

If this is a large file, bulk insert (after cleaning the dups) will be faster than row-by-row processing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文