1

我正在使用 SQL Server 2008

根据微软, http: //msdn.microsoft.com/en-us/library/ms188059.aspx

当我执行以下

set identity_insert on  
//insert statements here
set identity_insert off

列的标识设置为最大值。我可以避免这种情况吗?

考虑以下场景,

我的表有 2 行如下

id, name  comm  
1,  John, 232.43  
2,  Alex, 353.52  

现在使用上面的代码,当我插入

10, Smith, 334.23

根据上面的链接,SQL Server 自动将标识设置为 10。因此对于新插入的记录(不使用 identity_insert on),id 自动以 11 开头。

在使用 identity_insert on/off 之后,我希望标识值为 3

请帮忙。

4

4 回答 4

3

这是此讨论的测试表

create table t4721736 ( id int identity primary key, name varchar(10), comm money )
insert t4721736 select 'John', 232.43 -- id=1
insert t4721736 select 'Alex', 353.52 -- id=2

-- check contents    
select * from t4721736 

-- do all this in a transaction
BEGIN TRAN

-- dummy insert
insert t4721736 select 'dummy', null

-- get what the id should be
declare @resetto bigint
set @resetto = scope_identity()

-- remove dummy record
delete t4721736 where id = @resetto

-- perform the insert(s)
set identity_insert t4721736 on;
insert t4721736(id,name,comm) select 10000000, 'Smith', 334.23;
set identity_insert t4721736 off;

-- reset the identity
set @resetto = @resetto - 1  -- it needs to be 1 prior
DBCC CHECKIDENT(t4721736, RESEED, @resetto)

COMMIT

假设您完全理解(我相信您理解),一旦范围达到具有指定 ID 的记录,它就会失败。SQL Server 不会对已附加记录的 ID 执行任何自动跳过。

这不是问题,因为当我使用 identity_insert 插入时,id 的值将大于 1000 万。所以不会有碰撞的问题

要查看这是如何失败的,请通过在上面的代码中将“10000000”更改为“10”来缩短该过程。然后,跟进这些:

-- inspect contents, shows records 1,2,10
select * from t4721736

-- next, insert 7 more records, bringing the id up to 9
insert t4721736 select 'U3', 0
insert t4721736 select 'U4', 0
insert t4721736 select 'U5', 0
insert t4721736 select 'U6', 0
insert t4721736 select 'U7', 0
insert t4721736 select 'U8', 0
insert t4721736 select 'U9', 0

最后,尝试下面的下一个插入

insert t4721736 select 'U10', 0
于 2011-01-18T10:13:30.497 回答
2

您可以使用以下方法重置种子值DBCC CHECKIDENT

DBCC CHECKIDENT ("MyTable", RESEED, 3);
GO

但是,您已经插入了10的记录 ID ,所以是的,下一个确实是 11。

它记录在命令中:

如果表的当前标识值小于标识列中存储的最大标识值,则使用标识列中的最大值对其进行重置。

你不能两全其美。要么有最低的 ID 是基本种子的值,要么没有。

于 2011-01-18T08:13:13.533 回答
2

如果您要插入的这些行是特殊/魔术行(因此它们需要特定的 ID),您是否考虑过让这些行具有负 ID 值?这样就不会发生冲突,并且 IDENTITY 值不会通过添加它们来重置。

如果您需要插入这些具有截然不同的 ID 值的行的其他原因,也许您可​​以扩展您的问题以提供一些相关信息 - 我们也许能够提供更好的解决方案。

于 2011-01-18T11:32:20.797 回答
0

解决“植入错误”困境的另一种方法是创建您自己的身份生成程序和跟踪表。该表包括下一个 ID 应该是的表名和值。这样,您可以随时将其重置为任何值。该过程将包括检查下一个生成的密钥是否存在的逻辑,如果确实存在,它将递增密钥,直到找到表中不存在的 ID 并将其传回给您。这必须在所有插入上实现才能正常工作。这可以通过触发器实现。缺点是比使用 Damien_The_Unbeliever 建议的负数更多的处理开销。

于 2011-01-19T05:50:24.850 回答