我有这个表结构:
表1:id, group_id, label, sort_order
键:PK: id, UNIQUE: group_id+sort_order, INDEX: group_id
示例数据:
id group_id label sort_order
50 1 Field 1 1
51 1 Field 2 2
52 1 Field 3 3
其中(group_id, sort_order)
是唯一键。
要更新前端记录的排列,{by sort_order
字段按顺序使用。用户可以通过在前端拖动标签来更新订单,前端传递id:52, 51,50
,然后将其视为新的订单/排序。
预期结果:
id group_id label sort_order
50 1 Field 1 3
51 1 Field 2 2
52 1 Field 3 1
该过程应使用新的sort_order
值更新所有3条记录。示例更新查询:
UPDATE Table1 SET sort_order = 1 WHERE id = 52 AND group_id = 1
但是,由于sort_order是唯一键的一部分,因此group_id,sort_order
键已存在,因此会抛出错误。
我做了一个hackish解决方法,我更新排序顺序两次,例如:将其更新为更高的值,例如:sort_order = actual_order + 1000
然后使用实际值再次更新,例如:sort_order = actual_order
。< / p>
什么是更好的方法?我应该完全删除唯一键吗?
-
修改
-
为了更好地了解问题,这是我的PHP代码:
示例fieldIds:52,51,50
或50,51,52
或51,52,50
。序列决定了新的排序。
public function updateSort($projectId, $groupId, $subgroupId, array $fieldIds)
{
// Other stuff
// ...
$statement = create_a_prepared_statement(); // ...
// Updating sort_order directly would result to unique key violation
// so change the sort_order into some negative numbers and re-sort with
// the actual orders
foreach ($fieldIds as $sortIndex => $fieldId) {
$sort = $sortIndex - 1000;
$statement->execute(array(
'id' => $fieldId,
'project_id' => $projectId,
'group_id' => $groupId,
'subgroup_id' => $subgroupId,
':0' => $sort,
));
}
// Now sort it correctly
foreach ($fieldIds as $sortIndex => $fieldId) {
$sort = $sortIndex + 1;
$statement->execute(array(
'id' => $fieldId,
'project_id' => $projectId,
'group_id' => $groupId,
'subgroup_id' => $subgroupId,
':0' => $sort,
));
}
return true;
}
答案 0 :(得分:1)
考虑您在本声明中所写的内容:
I did a hackish workaround where ...
我会执行该短语的前半部分,
sort_order = actual_order + 1000
然后停止(意味着你已经完成)。
您将永远不会在100年内遇到最大值溢出。如果这是令人担忧的,请让您的年度活动(通过创建活动)提醒您距离它有多远,并将该组重新调整为1+,等等。
但是您需要更新任何给定组 2M 次以获得溢出。
答案 1 :(得分:0)
如果有这样严格的约束,则必须使用中间值:
import java.util.*;
import javax.swing.*;
public class FibonacciArrayList {
public static ArrayList<Integer> Fibonacci (Integer Max){
ArrayList<Integer> A = new ArrayList<Integer>();
int n0;
int n1;
int n2;
for(int i= 0; i = max; i++){
n2= n1 + n0;
system.out.println(n2);
n0=n1;
n1=n2;
return A;
}
public static void main (String[] arg){
Integer max;
String Title = "Fibonacci ArryList";
String data = JOptionPane.showInputDialog(null, "Enter the upper bound", Title, 1);
max = new Integer(data);
ArrayList<Integer> A = Fibonacci(max);
System.out.println("There are " + A.size()+ " Fibonacci numbers less than "+max);
}
}
UPDATE Table1 SET sort_order = -1 WHERE id = 52 AND group_id = 1;
UPDATE Table1 SET sort_order = 3 WHERE id = 50 AND group_id = 1;
UPDATE Table1 SET sort_order = 1 WHERE id = 52 AND group_id = 1;
是中间值。
整个过程:
因此,为了保持约束,您将始终更新2条记录,1条记录甚至2条记录。
答案 2 :(得分:0)
从它的外观来看,您的前端正在生成一次更新一行的更新语句。如果更新语句在任何时候导致2行具有相同的值,则将导致唯一的键冲突。我认为您应该研究一种方法来在一个语句中使用排序值更新所有行。我不熟悉mysql,但我熟悉sql server。在sql server中,我会将表复制到临时表,并在那里找出新的排序。然后执行update语句以在一个语句中将新排序值复制回原始表。
答案 3 :(得分:-1)
您可以使用case语句立即更新所有内容
UPDATE Table1 set sort_order =
CASE
WHEN id = 50 THEN 3
WHEN id = 51 THEN 1
WHEN id = 52 THEN 2
END