我有一个设置了自动增加ID的表。 假设我有ID 1,2,3,4和5.当我删除ID 3时,我希望ID 4下降到3,ID 5下降到4。
这可能吗?这是怎么做到的?
答案 0 :(得分:4)
我认为您希望保持记录ID的顺序,并且不希望它们之间有任何漏洞:)
这当然是可能的,但你应该让自己远离这样的解决方案。如果你以后开始将你的桌子彼此联系起来,你会后悔这个想法并疯狂地跟踪所有桌子的外国身份证。
真的,记录之间有漏洞确实不是一件坏事。此外,这就是实际的数据库逻辑的工作原理。使用ID时,就完成了。你不会再使用它了。当它不存在时,你会明白它已经消失了。这个问题的数据库跟踪最后使用的数字(对于ID列)和自动增量,而不是最后一个现有记录的ID,而是最后使用的记录的ID。
简而言之,你可以。但你不会想要它。
我刻意没有解释它是如何完成的。在此之前,我想确保这是OP真正想要的。
关于OP的评论It is what I really want :) There will be no other tables connected to it.
我可以想到一个简单的解决方案,它不需要任何数据库交互,因为OP现在承担责任。
创建没有自动递增ID字段的表。您的ID字段应为int类型。当您创建记录时,通过订购ID desc(从大到小)获取表中的最后一个ID,并从中获取TOP 1
。您的请求的示例查询:
SELECT TOP 1 ID FROM Table ORDER BY ID DESC
在新的INSERT查询中使用结果+ 1。
删除值时,应迭代所有记录并在for循环中逐个更新其ID。这意味着,如果你有数千条记录,并且没有使用数据库系统的内部功能(这里你不能因为你使用自己的逻辑),它可能需要一段时间(你已经被警告了!)。也就是说,如果你与其他表没有任何关系。如果这样做,则必须为相关表重复该迭代,以便保持外部ID关系(不再由DB维护)。因为,通过违反DB的内在逻辑,您掌握了控制权,现在您有责任跟踪和修改您自己的所有内容。我是否提到您不能在任何相关表中使用标识列,因为它不允许您将ID更改为其相关表中不存在的ID?
如你所见,这是一个痛苦的过程,你应该避免。在你了解真正发生的事情之前,有些事情可能根本没有意义。但相信我,我们都在那里。这些系统的构建背后有一个逻辑。无需重新发明轮子。当有人告诉你不去那里时,你真的可能想要考虑一下。 :)
祝你好运!
编辑:删除记录时,应使用服务器端代码来获取和更新每一行。这是逻辑。获取表行的总数。在循环外部创建一个全局变量,并计算循环内增加一个的get请求。开始循环(具有行总数的长度)。从底部开始(从第一行开始,ID为1)。如果获取请求的结果为null,则控制每一行。如果有空,请跳过并转到下一步。直到找到真实记录。获得它后,立即通过向数据库发送INSERT查询,使用您在循环外创建的全局变量更新它的ID。你的循环将使用该逻辑完成每一行并完成。
我从来没有写过这些详细的答案,除了OP之外别无他人。但你很幸运。请仔细阅读,不要忘记从现在开始你就是独自一人。
答案 1 :(得分:2)
可以将您的任务视为一个向上计数的简单计数器列。
如果这是真的,请想象一下这个表items
:
realID | field_x | field_y
-------+----------+--------
1001 | bla | blubb
1003 | bla2 | blubb2
1004 | bla+ | blubbs
现在看一下:
select count(i2.realId) as counter, i1.field_x, i1.field_y
from items i1 left join items i2 on i2.realID <= i1.realID
结果是:
counter | field_x | field_y
--------+---------+--------
1 | bla | blubb
2 | bla2 | blubb2
3 | bla+ | blubbs
我没有检查错别字,但结构肯定会起作用。我们的想法是将表连接到自身,即计算所有记录的ID的方式,该记录的id小于或等于表中相应的记录。这就是为什么它在计算。
像这样,你的专栏只是虚拟的,你不必“重新计票”。如果您需要它更永久,您可以将记录存储在临时中间表中。
但是无论何时使用join
中的范围,都要非常小心,并期待性能问题。