2009-06-12 63 views
4

我遇到了一個奇怪的問題,我需要一些幫助,試圖找出它。在標識列上的SQL Server 2005主鍵違規

我有一個數據庫,除了所有的應用程序數據列之外,還有一個ID列(定義爲int not null,Identity,從1開始,增加1)。該表的主鍵是ID列,沒有其他組件。

由於應用程序必須允許多次提交相同數據,因此沒有可用作「自然主鍵」的數據集。

我有一個存儲過程,這是添加新記錄到表中的唯一方法(除了登錄到服務器直接作爲數據庫所有者以外)

雖然QA今天上午測試應用程序,他們對在數據庫中輸入一條新記錄(按照預期使用應用程序,並且像過去兩週一樣),並在此表中遇到主鍵違例。

這與我一直在做主鍵約10年的方式一樣,並且從來沒有遇到過這種情況。

有關如何解決此問題的任何想法?或者是這種宇宙射線故障之一在很長一段時間內出現一次。

感謝您的任何建議,你可以給。

奈傑爾

在下午1:15 EDT 6月12日編輯,以提供更多的信息

架構的簡化版本...

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團隊在得到錯誤後再次嘗試,並且能夠成功提交查詢,並且從那時起他們一直試圖複製它,並且迄今爲止尚未成功。

我真的很欣賞這些想法的人。

+0

嗯......任何機會,你可以粘貼一個消毒表架構和/或有問題的插入語句? – ristonj 2009-06-12 14:44:05

+0

您是否仍然無法添加新記錄,或者是否只發生一次? – 2009-06-12 14:44:36

+0

查看下面我的答案奈傑爾... – Eric 2009-06-12 16:05:11

回答

1

基於經驗的隨機想法

你是否與Red Gate Data Compare等數據同步。這可以選擇重新設置標識列。這是造成使用問題。另一個項目上個月。

您也可能已經明確加載/同步了ID。

+0

不,這發生在兩週前專門爲QA設計的數據庫。 該數據庫是從VSTS Team Suite 2008版本部署的,並填充了500條生成的記錄。從那以後,他們在問題報告前後添加了大約50條記錄。 – Nigel 2009-06-12 17:26:37

+0

有人運行了DBCC CHECKIDENT或SET IDENTITY_INSERT ON,然後 – gbn 2009-06-12 19:07:16

4

雖然我沒有關於潛在原因的解釋,但可以更改標識列的種子值。如果種子下降到表中下一個值已經存在的位置,那麼這肯定會導致你所看到的。嘗試運行DBCC CHECKIDENT (table_name),看看它給你帶來了什麼。

欲瞭解更多信息,請this page

+0

是的,那也是我的第一個直覺反應 - 表可能已被玩過並且IDENTITY值已被重置或其他東西。 – 2009-06-12 14:59:27

+1

或者有人在打開SET IDENTITY_INSERT ON時將值插入表中。 – 2009-06-12 15:01:13

6

聽起來就像是種子的身份被損壞或以某種方式重設。最簡單的解決方法是將種子重置爲標識列的當前最大值:

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

也許有人插入一些記錄登錄到服務器直接使用新標識明確地,那麼當身份自動遞增場達到這一發生了主鍵違規事件。

但宇宙射線是算法中一個很好的解釋;)

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 
. 
. 
. 

我感覺粘只是輸入它。但是每隔一段時間你碰到的人只是從來沒有完全理解一個標識列是什麼,我想確保這是排除。順便說一句:如果這是答案,如果只是刪除問題,我不會拒絕你,不要承認這是你的問題!

你能告訴我每年夏天都會僱用實習生嗎?

0

您是否在任何程序中使用了@@ identity或scope_identity()等函數?如果你的表有觸發器或多個插件,你可以回去了你想要

0

主鍵違規不一定來自該表。

該應用程序是否觸及任何其他表或調用該函數的任何其他存儲過程?桌子上有觸發器嗎?或者存儲過程本身使用任何其他表或存儲過程?

特別是,審計表或觸發器可能會導致此問題。