2013-10-22 29 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()