SQL Server删除ID列上的值

SQL Server删除ID列上的值,sql,sql-server,sql-delete,auto-increment,window-functions,Sql,Sql Server,Sql Delete,Auto Increment,Window Functions,在我的数据库中,ID有一列,其中设置为“自动增量” 例如,当我删除一行,其中ID=2并插入一个新行时,ID的值为3 问题是如何在操作删除时将ID return设置为2而不是3 我使用的是Microsoft SQL Server 2012。与其他数据库中的大多数其他自动增量实现一样,SQL Server的标识列不提供任何选项来“填补数字浪费时留下的空白”(这不仅可能发生在删除行时,也可能发生在回滚事务或服务器重新启动时) 这是明确规定的: 列上的identity属性不能保证以下内容: [……] 值

在我的数据库中,
ID
有一列,其中设置为“自动增量”

例如,当我删除一行,其中
ID=2
并插入一个新行时,ID的值为3

问题是如何在操作删除时将ID return设置为2而不是3


我使用的是Microsoft SQL Server 2012。

与其他数据库中的大多数其他自动增量实现一样,SQL Server的标识列不提供任何选项来“填补数字浪费时留下的空白”(这不仅可能发生在删除行时,也可能发生在回滚事务或服务器重新启动时)

这是明确规定的:

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

[……]

值的重用-对于具有特定种子/增量的给定标识属性,引擎不会重用标识值

如果出于显示目的,需要在删除行时重置一个不断增加的值,可以在
选择
查询中使用
行号()

select t.*, row_number() over(order by id) new_id
from mytable t
如果要定期使用该表,可以创建一个视图,然后可以查询该视图,而不是原始表:

create view myview as
select t.*, row_number() over(order by id) new_id
from mytable t;

select * from myview;

删除后,您可以使用CHEKIDENT数据库控制台命令更改表的标识值,尽管只有在删除最后一条记录时才应使用此命令

DBCC CHECKIDENT('YourTable', RESEED, 2)

我不认为你真的想这么做。您现在可能看不到它,但有一个标识列,它将始终标识已删除的行,这是一件好事

如果您需要一个列以不同的方式工作,只需创建一个新列并应用业务规则,使其以您想要的方式工作即可


称之为ID_NOGAP,然后确保没有间隙。您可以在数据访问层或使用DB上的触发器(不推荐)执行此操作。

自动增量值始终递增,即使您删除了行。感谢您的回复,因此没有其他方法可以解决此问题?为什么在自动递增列中存在间隙会成为问题?自动递增列称为代理键。它的目的是唯一可识别的,并且需要在可能回滚或不回滚的事务之间可靠地工作。你所描述的行为在某些情况下是不可能的。它还违反了专栏只为一个目的和一个目的服务的前提。由于您希望显示一个用户友好的序列号,所以应该使用新列,而不是重用现有列。可能使用ROW_NUMBER()或类似工具。无论如何,这闻起来很像sql反模式。您可能解决了错误的问题。
“因此没有其他方法来解决此问题?”
什么问题?这就是数据库的工作方式。实际上,保留丢失的空间要好得多。这有助于解决许多情况。例如,如果有人将一个按ID查找记录的旧URL添加为书签,您不希望他们看到错误的数据。您只需发布更新而不是删除更安全。至少你可以在交易中做到这一点。