Sql server SQL Server重复使用同一标识Id两次

Sql server SQL Server重复使用同一标识Id两次,sql-server,tsql,Sql Server,Tsql,我希望这个问题不要太笼统 我有一个具有PK标识列Id的table Person 通过C,我为Person插入新条目,并为添加的3个人将Id设置为1,2,3 同样通过C,我对Id=1,2,3的人执行所有删除操作,这样表中就没有人了 之后,我运行了一些更改脚本,我无法发布它们,因为它们也太长了 我不做任何补种 现在有趣的是: 如果我调用SELECT IDENT_CURRENT'Person',它将显示3而不是4 如果我再次插入Person,我会得到一个Id为3的Person,而不是Id为4的Pers

我希望这个问题不要太笼统

我有一个具有PK标识列Id的table Person

通过C,我为Person插入新条目,并为添加的3个人将Id设置为1,2,3

同样通过C,我对Id=1,2,3的人执行所有删除操作,这样表中就没有人了

之后,我运行了一些更改脚本,我无法发布它们,因为它们也太长了

我不做任何补种

现在有趣的是:

如果我调用SELECT IDENT_CURRENT'Person',它将显示3而不是4

如果我再次插入Person,我会得到一个Id为3的Person,而不是Id为4的Person

你知道为什么会这样吗

编辑

我想我找到了对我问题的解释:

在通过SQLServerManagementStudio执行数据库更改时,设计器创建 临时表Tmp_Person,并将数据从Person移动到其中。之后,他对Tmp_进行了一个人对一个人的重命名。由于这是一个新表,索引将从头开始

标识属性不能保证唯一性。这就是主键或唯一索引的用途。备注部分的文档中包括了这一点,以及其他预期行为:

列上的identity属性不能保证以下内容:

值的唯一性-必须使用主键或唯一约束或唯一索引来强制唯一性

事务中的连续值-插入多行的事务不保证获得行的连续值 因为表上可能会发生其他并发插入。如果值 必须是连续的,则事务应使用独占锁 或使用可序列化隔离级别

服务器重新启动或其他故障后的连续值-SQL server可能会出于性能原因和某些原因缓存标识值 在数据库或服务器发生故障时,分配的值可能会丢失 重新启动。这可能导致插入时标识值出现间隙。如果 如果不接受间隙,则应用程序应使用自己的间隙 生成键值的机制。使用带有 NOCACHE选项可以将间隙限制为从不存在的事务 承诺

值的重用-对于具有特定种子/增量的给定标识属性,引擎不会重用标识值。如果 特定的insert语句失败或如果insert语句被滚动 那时,消耗的标识值将丢失,并且不会被删除 再次生成。这可能会导致在后续标识 生成值

这些限制是设计的一部分,以改进 性能,因为它们在许多常见的应用程序中都是可接受的 情况。如果由于这些原因而无法使用标识值 限制,创建一个单独的表,其中包含当前值和 使用您的 应用程序


强调我的问题。

我写了PK Identity专栏:但它确实保证了引擎不会重用标识值,问题指出他们看到了3次,然后看到了关于重用@gsharp值的后一点。IDENTITY不会有意重用某个值,但这并不意味着如果有人重新设置表的种子,它也不会。如果您停止了重复使用ID,那么不要从表中删除行;使用某种列表示行不再处于活动状态,并适当地编写查询。@标识实际上不会停止值的重用;如果发出重新设定种子,您甚至可以在同一个表中有两行具有相同ID。它不会自行返回并重用以前的值,这是正确的,但它不会阻止有人强迫它这样做。这很可能意味着OP或其他人已经为表格重新设定了种子。除非您可以共享代码来重现这一点,否则这里没有任何答案。几乎可以肯定的是,在更改脚本中,我无法发布它们,因为它们太长了。@SeanLange yep。我想我找到了问题所在。看我的编辑。看来你当时回答了。猜你在使用GUI在表中间添加一个列,@ GPACK,而不是使用ALTURE语句在结尾添加它?使用GUI是有用的,但它可能并不总是像您所想的那样。