Identity列上的Sql Server 2005主键冲突

时间:2009-06-12 14:40:46

标签: sql-server identity-column primary-key

我遇到了一个奇怪的问题,我需要一些帮助才能弄明白。

除了所有应用程序数据列之外,我还有一个数据库,其中包含ID列(定义为int not null,Identity,从1开始,递增1)。该表的主键是ID列,没有其他组件。

由于应用程序必须允许多次提交相同数据,因此没有可用作“自然主键”的数据集。

我有一个存储过程,这是将新记录添加到表中的唯一方法(除了直接以db所有者身份登录服务器)

虽然QA今天早上正在测试应用程序,但他们要在数据库中输入一条新记录(使用应用程序按预期进行,并且过去两周一直在进行)并遇到主键违规表

这与我十年来一直在做主键的方式相同,并且从未遇到过这种情况。

有关如何解决此问题的任何想法?或者这是长时间出现的宇宙射线故障之一。

感谢您提供任何建议。

美国东部时间6月12日下午1点15分编辑,以提供更多信息

架构的简化版......

CREATE TABLE [dbo].[tbl_Queries](
[QueryID] [int] IDENTITY(1,1) NOT NULL,
[FirstName] [varchar](50) NOT NULL,
[LastName] [varchar](50) NOT NULL,
[Address] [varchar](150) NOT NULL,
[Apt#] [varchar](10) NOT NULL
    ... <12 other columns deleted for brevity>
[VersionCode] [timestamp] NOT NULL,
 CONSTRAINT [PK_tbl_Queries] PRIMARY KEY CLUSTERED 
(
    [QueryID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

(也删除了默认值语句)

存储过程如下

insert into dbo.tbl_Queries
    (   FirstName,
        LastName,
        [Address],
        [Apt#]...) values
    (   @firstName,
        @lastName,
        @address,
        isnull(@apt, ''), ... )

它甚至没有查看标识列,不使用IDENTITY,@@ scope_identity或类似的东西,它只是一个文件而忘记了。

我尽可能地确信身份值没有重置,并且没有其他人使用直接数据库访问来输入值。此项目中唯一使用标识插入的时间是在初始数据库部署中,以在查找表中设置特定值。

QA团队在收到错误后立即再次尝试,并且能够成功提交查询,并且从那时起他们一直在尝试重现它,并且到目前为止还没有成功。

我真的很欣赏这些想法。

8 个答案:

答案 0 :(得分:6)

听起来身份种子被破坏或以某种方式重置。最简单的解决方案是将种子重置为标识列的当前最大值:

DECLARE @nextid INT;
SET @nextid = (SELECT MAX([columnname]) FROM [tablename]);
DBCC CHECKIDENT ([tablename], RESEED, @nextid);

答案 1 :(得分:4)

虽然我没有关于潜在原因的解释,但是有可能更改标识列的种子值。如果将种子降低到表中已存在下一个值的位置,那么这肯定会导致您所看到的内容。尝试运行DBCC CHECKIDENT (table_name)并查看它为您提供的内容。

有关详细信息,请查看this page

答案 2 :(得分:1)

基于经验的随机思考

您是否已将数据与Red Gate Data Compare同步。这可以选择重新设置标识列。它导致了使用问题。还有上个月的另一个项目。

您也可能已明确加载/同步ID。

答案 3 :(得分:0)

也许有人使用新的ID明确地插入一些记录到服务器的记录,然后当身份自动增量字段达到此数字时发生主键违规。

但宇宙射线是一个很好的解释;)

答案 4 :(得分:0)

只是为了非常非常确定...你在存储过程中没有使用IDENTITY_INSERT吗?像这样的逻辑:

declare @id int;
Set @id=Select Max(IDColumn) From Sometable;
SET IDENTITY_INSERT dbo.SomeTable ON
Insert (IDColumn, ...others...) Values (@id+1, ...others...);
SET IDENTITY_INSERT dbo.SomeTable OFF
.
.
.

只要输入它就感觉很粘。但每隔一段时间就会碰到那些从未完全明白Identity列的内容的人,我想确保排除这一点。顺便说一句:如果这是答案,如果只是删除问题并且从不承认这是你的问题,我不会反对你!

你能告诉我每年夏天都聘请实习生吗?

答案 5 :(得分:0)

您是否在任何程序中使用@@ identity或scope_identity()等函数?如果您的表有触发器或多个插入,您可能会找回所需表的错误标识值

答案 6 :(得分:0)

希望事实并非如此,但SQL 2005中存在一个已知错误,其中包含SCOPE_IDENTITY(): http://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=328811

答案 7 :(得分:0)

主键违规不一定来自该表。

应用程序是否触及任何其他表或调用该函数的任何其他存储过程?桌子上有没有触发器?或者存储过程本身是否使用任何其他表或存储过程?

特别是,审核表或触发器可能会导致此问题。