首页 > 解决方案 > “无法在对象中插入重复的键行”与“违反 UNIQUE KEY 约束”之间的区别

问题描述

当我们得到“违反唯一键约束'XXXXXXX'”与“无法在具有唯一索引'XXXXXXX'的对象'dbo.XXXXXX'中插入重复的键行”时,是否是相同的sql异常。在我的服务器端代码中,我们曾经使用以下方式处理此问题:

catch (SqlException sqlEx)
{
  if (sqlEx.Message.Contains("Violation of UNIQUE KEY constraint 'XXXXX'"))
  {
    .....
  }
}

但是现在sql server没有提示错误“违反UNIQUE KEY约束'XXXXXX'”,而是说“无法在具有唯一索引'XXXXXX'的对象'dbo.XXXX'中插入重复的键行”。

在 MSSQL 的配置中,有没有办法让我得到一个描述性的 sql 异常并返回文本“违反 UNIQUE KEY 约束”?

标签: asp.netsql-serversql-server-2008

解决方案


当您尝试插入违反表上唯一约束的行时,会发生第一个错误。
第二个错误发生在行违反唯一索引时。这是一个微妙的差异,坦率地说,我真的不知道为什么会有两个不同的错误,特别是考虑到在 SQL Server 中使用唯一索引实现了唯一约束。

无论如何,我不会使用错误消息来指示您遇到了什么错误。相反,我会检查错误号,它在 SqlException 类中作为一个名为 - 惊喜 - Number的 int 属性公开。

您可以通过查询获得所有错误消息的列表及其相关编号sys.messages。我已经在 text 上使用 like 谓词来完成此操作,以获得与您的问题相关的错误:

SELECT message_id, [Text]
FROM sys.messages 
WHERE [Text] LIKE '%Cannot insert duplicate key%'

哪个返回:

message_id  Text
2601        Cannot insert duplicate key row in object '%.*ls' with unique index '%.*ls'. The duplicate key value is %ls.
2627        Violation of %ls constraint '%.*ls'. Cannot insert duplicate key in object '%.*ls'. The duplicate key value is %ls.

(感谢 Larnu 的欺骗建议,我找到了Database Engine Errors的链接,但是查询数据库比加载该页面要快...)

catch因此,将块中的 c# 代码更改为

// Cannot insert duplicate key..., Violation of UNIQUE KEY...
if (new int[] {2601, 2627}.Contains(sqlEx.Number))
{
  ....
}

推荐阅读