我在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。
我该如何解决这个问题?
答案 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值的顺序。