我希望这个问题不要太笼统。
我有一个表Person
,其中有一个PK标识列Id
。
通过C#,我为Person
插入了新条目,并将添加的3个人的ID设置为1,2,3。
同样通过C#,我对ID = 1,2,3的人员执行所有删除操作,以使表中不再存在任何人员。
然后,我还在Table Person上运行了一些更改脚本(由于它们太长,所以无法发布它们)。
我不做任何RESEED。
现在很有趣:
如果我拨打SELECT IDENT_CURRENT('Person')
,则显示3而不是4。
如果我再次插入Person,则会得到一个ID为3而不是ID为4的Person。
任何想法为什么会发生以及如何发生?
编辑
我想我找到了我的问题的解释:
在通过SQL Server Management Studio执行数据库更改时,设计器将创建 临时表Tmp_Person并将数据从其中的Person移动到那里。之后,他将Tmp_Person重命名为Person。由于这是一个新表,因此索引将从头开始。
答案 0 :(得分:1)
IDENTITY
属性不能保证唯一性。这就是PRIMARY KEY
或UNIQUE INDEX
的用途。备注部分的文档中涵盖了此内容,以及其他预期的行为。 CREATE TABLE (Transact-SQL) IDENTITY (Property) - Remarks:
列上的identity属性不能保证满足以下条件:
值的唯一性-必须通过使用PRIMARY KEY或UNIQUE约束或UNIQUE索引来强制唯一性。
事务中的连续值-不能保证插入多行的事务获取行的连续值 因为其他并发插入可能会在表上发生。如果值 必须是连续的,则交易应使用排他锁 或使用SERIALIZABLE隔离级别。
服务器重新启动或其他故障后的连续值-出于性能原因和某些原因,SQL Server可能会缓存标识值 在数据库故障或服务器期间,分配的值可能会丢失 重新开始。这可能导致插入时身份值出现空白。如果 差距是不可接受的,那么应用程序应该使用自己的 生成键值的机制。将序列发生器与 NOCACHE选项可以限制与从未交易的差距 承诺。
值的重用-对于具有特定种子/增量的给定身份属性,引擎不会重用身份值。如果一个 特定的插入语句失败或插入语句已滚动 然后,消耗的身份值将丢失,并且不会 再次产生。这可能会导致在后续标识时出现空白 值生成。
这些限制是设计的一部分,目的是改善 性能,并且因为它们在许多常见情况下都可以接受 情况。如果由于这些原因而无法使用身份值 限制,创建一个包含当前值的单独表,并 使用以下命令管理对表格的访问和号码分配 应用。
强调这个问题。