插入新记录时,表ID(PrimaryKey)不会以正确的顺序递增

时间:2013-07-11 09:39:17

标签: sql sql-server-2008

当我使用SQL Server 2008及其Management Studio删除表中的记录,然后插入新记录时,主键列的顺序不按顺序排列。

假设我使用record_id = 5删除Record5。表留下4个记录,即Record1,Record2,Record3,Record4

现在,当我插入新记录时,其ID(主键)自动设置为6.我需要SQL Server将其设置为5.

因为当我在Asp.Net(c#)的gridView中显示此表时看起来很奇怪,我的表的record_id列序列类似于1, 2, 3, 17, 18, 29等,

看起来很糟糕。请帮忙。

由于

4 个答案:

答案 0 :(得分:3)

无法保证IDENTITY值不会有间隙。事实上很可能会遇到这样的差距。您必须以适应和期望身份值存在此类差距的方式设计您的应用程序。要在网格中显示行号,到目前为止,最好的选择是使用本地客户端(ASP.Net或甚至浏览器端JS)计数器。您可以使用ROW_NUMBER()生成计数器服务器端,但与客户端相比,它不是最佳选项。

答案 1 :(得分:2)

您需要从数据库中的标识列单独订购数据显示。标识列不是“显示顺序”,事实上,它没有任何可辨别的顺序 - 它总是有空洞。

考虑一个包含4行的表。现在添加5,然后删除5行。您输入的下一列的ID为10,即使表中只有5行。

所以,不要再依赖它了。而是使用Container.ItemIndex并使用它来显示正在显示的行数的适当计数。

答案 2 :(得分:1)

这听起来令人难以置信,但如果你想要一个递增的记录号,SQL Server就不支持你了。回滚或重新启动服务器的事务可能会在数字中留下漏洞。

对于严格增加的订单,您必须推出自己的实施。一种常见的解决方案是创建一个包含最近分发的数字列表的表。如果以原子方式检索并增加数量,那就是线程安全的。例如:

update  NumbersTable
set     Nr = Nr + 1
output  deleted.Nr
where   Type = 'OrderNumber'

另一种选择是动态检索最高订单号。通过适当的锁定提示,可以以线程安全的方式完成:

insert  OrdersTable
        (OrderNr, col1, col2, col3)
select  isnull((
        select  max(OrderNr) + 1
        from    OrdersTable with (tablock, holdlock)
        ), 1)
,       'value1'
,       'value2'
,       'value3'

如果删除一行,则必须手动实现。假设存在记录1,2和3。您删除记录2.新订单应该包含多少个数字?如果你说2,请记住这意味着订单2是在订单3之后创建的,这会让很多人感到困惑。

答案 3 :(得分:0)

删除语句后运行此查询。

declare @a int

set @a =(select max(identity_column_name) from table_name)
--print @a

dbcc checkident(table_name,reseed,@a)