如果我有三个菜单
id | name | order
--------------------
1 | Foo | 1
2 | Bar | 2
3 | Blah | 3
并点击链接menu/up/1
,我需要设置标识为1
到2
的菜单和标识为2
到1
的菜单。< / p>
我试过(PDO)
public static function goDown($id) {
if(!$id) {
return false;
}
self::connect();
self::prepare('SELECT count(*) FROM menu');
$count = self::fetch();
if(isset($count['count(*)'])) {
self::prepare('UPDATE menu SET order = order - 1 WHERE order = :count');
self::bindValue('count', $count['count(*)']);
self::execute();
self::prepare('UPDATE menu SET order = order + 1 WHERE id = :id AND order < :count');
self::bindValue('id', $id);
self::bindValue('count', $count['count(*)']);
return self::execute();
}
}
谢谢!
编辑 - 我的解决方案:
public static function goDown($id) {
if(!$id) {
return false;
}
self::connect();
self::prepare('SELECT count(*) FROM menu');
$count = self::fetch();
if(isset($count['count(*)'])) {
self::prepare('SELECT ordem FROM menu WHERE id = :id LIMIT 1');
self::bindValue('id', $id);
$ordem = self::fetch();
self::prepare('UPDATE menu SET ordem = ordem - 1 WHERE ordem = :ordem');
self::bindValue('ordem', $ordem['ordem'] + 1);
self::execute();
self::prepare('UPDATE menu SET ordem = ordem + 1 WHERE id = :id AND ordem < :count');
self::bindValue('id', $id);
self::bindValue('count', $count['count(*)']);
return self::execute();
}
}
答案 0 :(得分:1)
我不知道你的表定义和键是如何设置的,但你可能需要一段重叠的数字。如果可以,那就做这样的事情:
最安全的:
SELECT order FROM menu WHERE id = :id; /* One to go up; */
SELECT id, order FROM menu WHERE order = :existingOrder + 1; /* One to go down */
UPDATE menu SET order = order + 1 WHERE id = :id; /* Putting it up */
UPDATE menu SET order = :existingOrder WHERE id = :existingId
这使用额外的查询,但更安全。您也可以验证它不在顶部/底部,因为这会导致问题。
答案 1 :(得分:0)
检查this。
将它转换为PDO很容易:
set @id := 10;
select @count := count(*) from t;
select @prevOrder := least(anorder + 1, @count) from t where id = @id;
select @prevId := id from t where anorder = @prevOrder;
update t set anorder = anorder - 1 where id = @prevId;
update t set anorder = anorder + 1 where id = @id;
基本上它会降低所选ID(@id
)的顺序而不会下降(这是least
函数)并增加之前在那个地方的ID。