【问题标题】:Best way to catch sql unique constraint violations in c# during inserts在插入期间在 c# 中捕获 sql 唯一约束违规的最佳方法
【发布时间】:2014-09-04 14:18:45
【问题描述】:

我在 c# 中有一个循环插入到表中。很基本的东西。当违反唯一约束时抛出的异常对象是否有一些东西可以用来查看违规值是什么?

或者有没有办法在sql中返回它?我有一系列文件,它们的数据正在加载到表格中,我正在努力寻找骗子。

我知道我可以将一些纯粹基于 IO 的代码拼凑在一起,可以找到它,但我想要一些可以用作更永久解决方案的东西。

【问题讨论】:

  • 如果你使用循环插入到 SQL 表中你做错了
  • 在不知道场景的情况下说“错误”有点苛刻,但可能有更好的方法来做到这一点
  • 为什么会出错或效率低下?将我链接到一些有关正确方法的文献。我还在学习。谢谢。
  • 重复调用服务器可能代价高昂
  • 如何避免重复的服务器调用?我使用 ADO.Net,所以你是在说 SqlBulkCon 吗?我通常将循环包装在带有 sqlconnection 对象的 using 语句中。如果有人可以提供更有效的方法,请提供链接?将不胜感激。

标签: c# sql-server ado.net


【解决方案1】:

您要查找的是 SqlException,特别是违反主键约束。通过查看抛出的异常的 number 属性,您可以从此异常中获取此特定错误。这个答案可能与您需要的有关: How to Identify the primary key duplication from a SQL Server 2008 error code?

总而言之,它看起来像这样:

// put this block in your loop
try
{
   // do your insert
}
catch(SqlException ex)
{
   // the exception alone won't tell you why it failed...
   if(ex.Number == 2627) // <-- but this will
   {
      //Violation of primary key. Handle Exception
   }
}

编辑:

这可能有点老套,但您也可以只检查异常的消息组件。像这样的:

if (ex.Message.Contains("UniqueConstraint")) // do stuff

【讨论】:

  • 可能不是PK错误,它可能是一个独特的约束(这是OP在问题中所说的)
  • 只要它捕获了一个约束,该约束表明重复记录(可能是任何一个)对我来说已经足够好了。我做了更多的研究,根据 sys.messages 表,消息是'违反 %ls 约束'%.*ls'。无法在对象“%.*ls”中插入重复键。我认为无论哪种情况都涵盖了我。不过,您的两个帖子都很有帮助。
【解决方案2】:

您可以将插入包装到一个存储过程中,该存储过程在插入之前首先验证没有重复项。这样,您就可以准确控制复制值时返回的内容。

此外,您可能会发现将插入逻辑转移到 SP 将允许您执行您似乎正在执行的批量插入,而无需重复调用数据库。

要回答您的实际问题:

Unique Key Violation in SQL Server - Is it safe to assume Error 2627?

【讨论】:

【解决方案3】:

你也可以这样做:

var result = DbCon.CheckForPrimaryKey(value).ToList();
if(result.Count() == 0)
       DbCon.InsertValue(value);
else
     // Do Nothing   

【讨论】:

    【解决方案4】:

    除了 Bill Sambrone 的回答,

    两个错误码用于检查唯一键违规

    1. 2601 - Violation in unique index
    2. 2627 - Violation in unique constraint (although it is implemented using unique index)

    您可以根据需要使用一种或两种:

    try
    {
    
    }
    catch(SqlException ex)
    {
       if(ex.Number == 2601) 
       {
          // Violation in unique index
       }
       else if(ex.Number == 2627)
       {
          // Violation in unique constraint
       }
    }
    

    try
    {
    
    }
    catch(SqlException ex)
    {
       if(ex.Number == 2601 || ex.Number == 2627)
       {
          // Violation in one on both...
       }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-06-05
      • 1970-01-01
      • 2013-11-27
      • 2023-03-30
      • 1970-01-01
      • 2011-11-26
      • 2022-01-23
      • 1970-01-01
      • 2015-11-03
      相关资源
      最近更新 更多