避免身份列中的差距

时间:2013-06-17 05:57:43

标签: sql-server sql-server-2008

我在MS SQL SERVER 2008中有一个表,我已将其primary key设置为自动递增,但如果我从该表中删除任何行并在表中插入一些新行,则从下一个标识值开始这造成了身份价值的差距。我的程序要求所有的身份或密钥都按顺序排列。

像: 赋值表总共有16行,带有序列标识(1-16),但是如果我删除第16位的值

Delete From Assignment Where assignment_id=16; 

并在此操作之后插入新行

Insert  into Assignment(assignment_title)Values('myassignment');

不是将16作为主键分配给这个新值,而是指定17。

我该如何解决这个问题?

4 个答案:

答案 0 :(得分:3)

重命名或重新编号主键值不是一个好的数据库管理实践。我建议您按原样保留主键,并使用您需要重新编号的值创建单独的列索引。然后简单地创建一个触发器来运行一个例程,该例程将按照您期望的顺序重新编号每一行,显然是通过寻找"间隙"并使用从先前值开始递增的值输入它们。

答案 1 :(得分:0)

这是SQL Server标准行为。如果您在示例中删除了ID = 8的行,则仍然会有间隙。

您所能做的就是在SQL Server中编写一个函数getSmallestDreeID,您为每个插入调用了一个函数,这将为您提供最小的未分配ID。但你必须非常谨慎地处理交易和ACID。

答案 2 :(得分:0)

如果没有一些后处理逻辑来重新编号行,则无法实现所需的行为。

考虑这样的情况:

会话1开始一个事务,插入一行(id = 16),但尚未提交。

会话2开始一个事务,插入一行(id = 17)并提交。

Session1回滚。

表中是否存在16将在17提交后决定。

你不能在触发器中重新编号,你会陷入僵局。

您可能需要做的是查询添加行序号的数据。

身份值的差距不是问题

答案 3 :(得分:0)

好吧,我最近遇到了同样的问题:我需要外部C#应用程序中的ID值才能检索名称与ID完全相同的文件。 ==>这是我为避免身份属性所做的,我手动输入了id值,因为它是一个小表,但如果不是你的情况,请使用SEQUENCE SQL Server 2014。 使用语句UPDATE而不是delete来保持id值的顺序。