需要一种方法来拦截MSSQL中的重复键异常

时间:2012-12-31 13:22:54

标签: sql-server exception-handling unique-constraint duplicate-data

让我们假设您的MSSQL 2008数据库中存在唯一的索引约束违规,如下所示:

Violation of PRIMARY KEY constraint 'PK_ManufacturerCode'. Cannot insert duplicate key in object 'dbo.ManufacturerCode'. The duplicate key value is (8410179)

目前我正在通过胖客户端中的全局异常处理程序处理此异常(使用ADO在Delphi 6中编写,但无关紧要,我计划将来使用C#.NET)并且附加异常消息一个日志框。

但我想亲自处理这个特定的重复密钥异常,并在客户端使用胖客户端自己的文本显示相应的错误消息。我可以解析匹配的错误消息,但不会这样做有两个原因:

  • 这不是一种正确的方法 - 依靠一些错误代码更好;
  • 胖客户端旨在使用各种语言的各种MSSQL服务器版本,这些版本可能有不同的错误文本

使用带有自定义退出代码的RETURN或不断调用特殊存储过程来检查重复项,这并不能让我高兴。

3 个答案:

答案 0 :(得分:3)

AFAIK,区分重复键异常的唯一方法是解析错误消息。

更好的解决方案是首先防止重复键异常。写插入不要插入重复键,如果添加了行,请与@@rowcount核对:

insert  YourTable
        (id, col1, col2)
select  1, 'a', 'b'
where   not exists
        (
        select  *
        from    YourTable yt2
        where   yt2.id = 1
        )

if @@rowcount = 0
    -- Duplicate key!

答案 1 :(得分:3)

幸运的是,您不必解析文本。 SqlException具有Number属性。 Oberserve,返回的是什么号码并匹配它。数字定义明确。您甚至可以在其中一个系统目录表中查看所有这些表(没有名称方便)。

你的一个非常好的想法是只捕获一个非常具体的错误,而不是只捕获所有SqlException(例如)。

答案 2 :(得分:3)

在ADO中,发生错误后您将访问连接Errors属性,并检查NativeError属性以获取SQL Server特定的错误编号。

当您切换到.NET时,相同的数字会显示为SqlExceptionSqlErrorNumber属性

但是,找到特定的错误编号可能有点麻烦 - 对于Duplicate Key,它的错误号为2627.