如果在两者之间添加了一些内容,我有一个查询来更新索引
update My_Table
set NS_LEFT = NS_LEFT + 10
where NS_THREAD = parentThread and NS_LEFT > oldRight
order by NS_LEFT desc
工作正常-
现在,如果我必须在两次删除之间删除某些内容,那么我将使用以下查询
update My_Table
set NS_LEFT = NS_LEFT - 10
where NS_THREAD = parentThread and NS_LEFT > oldRight
order by NS_LEFT desc
它不起作用并抛出重复索引错误-
[代码:1062,SQL状态:23000](conn = 1517)重复的条目“ 1-1110” 键“ INDEX”
索引(NS_THREAD,NS_LEFT)
如何解决删除元素
注意 这是我针对MariaDB的解决方案,仅适用于其他不支持OrderBy的其他数据库(为什么。对我来说,它仍然是一个悬而未决的问题)
答案 0 :(得分:2)
我过去在控制订单时所做的选择不是执行两次更新。第一个将组向上移动超过任何当前使用的值,以确保没有冲突。然后第二个将它们转移到应有的位置。在一般形式下,可以通过以下方式说明该想法:
UPDATE aTable SET somevalue = somevalue + 10000 WHERE somevalue > x;
UPDATE aTable SET somevalue = somevalue - 10000 - y WHERE somevalue > x + 10000;
“ 10000”只是将范围推到碰撞后的值,y是您实际要移动它们的量。显然,如果已经有10000左右的值,则该数字将需要不同。为了避免查询安全值,在设计允许的情况下,还有另一种选择。...
如果未使用负值,并且表格设计允许使用负数,则此过程的版本要更简单一些:
UPDATE aTable SET somevalue = somevalue * -1 WHERE somevalue > x;
UPDATE aTable SET somevalue = (somevalue * -1) - y WHERE somevalue < 0;
这假定通常不存在负值,并且为安全起见,应在事务内执行更新(以及原始删除),以使该解决方案的潜在并发应用程序不会冲突。 (编辑:请注意,交易/并发要求适用于我介绍的两种表格。)
编辑:哦,我刚刚注意到Gordon的回答非常相似...裸露的减号看起来像我屏幕上的斑点。如果戈登(Gordon)无法正常工作,那么也不会。
答案 1 :(得分:1)
发生了。一种解决方案是进行两次更新:
update My_Table
set NS_LEFT = - (NS_LEFT - 10)
where NS_THREAD = parentThread and NS_LEFT > oldRight
order by NS_LEFT desc;
update My_Table
set NS_LEFT = - NS_LEFT
where NS_THREAD = parentThread and NS_LEFT < 0;