SQL Server两次重复使用同一ID ID

时间:2019-04-15 16:06:05

标签: sql-server tsql

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

我有一个表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。由于这是一个新表,因此索引将从头开始。

1 个答案:

答案 0 :(得分:1)

IDENTITY属性不能保证唯一性。这就是PRIMARY KEYUNIQUE INDEX的用途。备注部分的文档中涵盖了此内容,以及其他预期的行为。 CREATE TABLE (Transact-SQL) IDENTITY (Property) - Remarks

  

列上的identity属性不能保证满足以下条件:

     
      
  • 值的唯一性-必须通过使用PRIMARY KEY或UNIQUE约束或UNIQUE索引来强制唯一性。

  •   
  • 事务中的连续值-不能保证插入多行的事务获取行的连续值   因为其他并发插入可能会在表上发生。如果值   必须是连续的,则交易应使用排他锁   或使用SERIALIZABLE隔离级别。

  •   
  • 服务器重新启动或其他故障后的连续值-出于性能原因和某些原因,SQL Server可能会缓存标识值   在数据库故障或服务器期间,分配的值可能会丢失   重新开始。这可能导致插入时身份值出现空白。如果   差距是不可接受的,那么应用程序应该使用自己的   生成键值的机制。将序列发生器与   NOCACHE选项可以限制与从未交易的差距   承诺。

  •   
  • 值的重用-对于具有特定种子/增量的给定身份属性,引擎不会重用身份值。如果一个   特定的插入语句失败或插入语句已滚动   然后,消耗的身份值将丢失,并且不会   再次产生。这可能会导致在后续标识时出现空白   值生成。

  •   
     

这些限制是设计的一部分,目的是改善   性能,并且因为它们在许多常见情况下都可以接受   情况。如果由于这些原因而无法使用身份值   限制,创建一个包含当前值的单独表,并   使用以下命令管理对表格的访问和号码分配   应用。

强调这个问题。