2013-10-22 49 views
0

錯誤: 將IDENTITY轉換爲數據類型爲int的算術溢出錯誤。 發生算術溢出。IDENT_CURRENT值高於最大值(id)

調試:

ID =我的標識列,數據類型INT。增量= 1,種子= 1

select max(id) as max, min(id) as min from eventlogreport 
    Result: 6728550 1 

select count(*) from eventlogreport 
    Result: 6728550 

到目前爲止,這樣做不錯。看起來我們有足夠的空間容納更多的行。但是插入600 000多行會導致溢出錯誤。更多調試。

SELECT IDENT_CURRENT ('EventLogReport') AS Current_Identity; 
    Result: 2147483647 

問題:

  1. 如何能在當前標識值如此之高時表不包含 行相同數量的,並且沒有IDS已經 跳過?
  2. 如何安全地將IDENT_CURRENT設置爲與max(id)相同的編號?或者,只要id列不是引用,可能更容易重新設置種子?
+0

爲什麼downvoting這個問題? – smarty

回答

3

身份值不參與事務 - 因此,如果您已經嘗試大量插入(在添加了所有當前行之後)後來被回滾,則IDENT_CURRENT可能比觀察到的最高值高得多表中的值。

同樣,如果您實際插入了2147483647行,但隨後刪除了ID大於6728550的所有行,則您會觀察到相同的情況。

第三,可能是有人補種的身份是2147483647

所以有很多方法,你可能已經達到了這種情況。我們不可能知道它是如何產生的。


要設置身份值以適合於下一個插入,使用DBCC CHECKIDENT兩次:

DBCC CHECKIDENT(Table,RESEED,1) 
DBCC CHECKIDENT(Table,RESEED) 

第一設置下一個值作爲2來使用。然後第二個調用這個部分:

If the current identity value for a table is less than the maximum identity value stored in the identity column, it is reset using the maximum value in the identity column. See the 'Exceptions' section that follows.

0

Ad.1 這是因爲identity是從表中有些獨立。交易對身份沒有影響,也有錯誤。如果您嘗試插入某些行,並且插入失敗,則無論如何都會爲這些行保留標識值。 此行爲的原因是,如果您有兩個事務正在執行插入操作,並且第一個事務將回滾,則第二個事務不必擔心填補第一個事務之後留下的空白。

兩個例子來演示行爲:

drop table _test 
GO 
create table _test(
    id int identity(1,1), 
    x tinyint 
) 
GO 

-- example 1 (insert error): 

insert into _test(x) 
select 1 as x union all 
select 2 union all 
select 256 
GO 

select * from _test 
select ident_current('_test') 
GO 

-- example 2 (rollback): 

begin tran 

    insert into _test(x) 
    select 1 as x union all 
    select 2 

rollback tran 


select * from _test 
select ident_current('_test') 
GO 

Ad.2 重新設定種子,如果你有身份;你不能「改變」IDENT_CURRENT()