当我使用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
等,
看起来很糟糕。请帮忙。
由于
答案 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)