0

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

假设我删除 Record5 与record_id = 5. 表剩下 4 条记录,即Record1,Record2,Record3,Record4.

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

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

它看起来很糟糕。请帮忙。

谢谢

4

4 回答 4

3

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

于 2013-07-11T09:50:25.540 回答
2

您需要将数据的显示与数据库中的标识列分开排序。标识栏不是为了“显示顺序”,事实上,它没有任何可辨别的顺序——它总会有孔。

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

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

于 2013-07-11T10:15:45.040 回答
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 之后创建的,这会让很多人感到困惑。

于 2013-07-11T09:49:51.250 回答
0

在您的 Delete 语句之后运行此查询。

declare @a int

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

dbcc checkident(table_name,reseed,@a)
于 2013-07-11T09:48:06.763 回答