我目前正面临一个问题,我无法解决。我正在为所有类别使用嵌套集,当我需要移动它们时,会出现某种错误。 我的问题是,如果我想移动一个节点 - 例如ID = 2,从“顶级”到底层ID = 1,在ID = 1 + Rgt = 2时L = 1,Lft = 4,ID = 2,Lft = 3,那么它将全部工作。
问题是,如果我尝试将ID = 2的节点移动到最后一个节点 - ID = 5,Rgt = 9,Lft = 10,那么它真的毁了我的桌子 - 我看不清楚是什么在mySQL查询中出错 - 希望你能帮忙......
我开始时的表格是这样的:
ID | Name | Rgt | Lft | ParentID
---+-------------+------+-----+---------
1 | Trousers | 1 | 2 | 0
---+-------------+------+-----+---------
2 | Jeans | 3 | 4 | 0
---+-------------+------+-----+---------
3 | Tops | 5 | 6 | 0
---+-------------+------+-----+---------
4 | T-shirts | 7 | 8 | 0
---+-------------+------+-----+---------
5 | Shirts | 9 | 10 | 0
---+-------------+------+-----+---------
我的查询是这样的:
SELECT
@node_id := '2',
@node_pos_left := '3',
@node_pos_right := '4',
@parent_id := '5',
@parent_pos_right := '10';
SELECT
@node_size := @node_pos_right - @node_pos_left + 1;
UPDATE ss_C_Categories
SET Lft = 0-(Lft), `Rgt` = 0-(Rgt)
WHERE Lft >= @node_pos_left AND Rgt <= @node_pos_right;
UPDATE ss_C_Categories
SET Lft = Lft - @node_size
WHERE Lft > @node_pos_right;
UPDATE ss_C_Categories
SET Rgt = Rgt - @node_size
WHERE Rgt > @node_pos_right;
UPDATE ss_C_Categories
SET Lft = Lft + @node_size
WHERE Lft >= IF(@parent_pos_right > @node_pos_right, @parent_pos_right - @node_size, @parent_pos_right);
UPDATE ss_C_Categories
SET Rgt = Rgt + @node_size
WHERE Rgt >= IF(@parent_pos_right > @node_pos_right, @parent_pos_right - @node_size, @parent_pos_right);
UPDATE ss_C_Categories
SET
Lft = 0-(Lft)+IF(@parent_pos_right > @node_pos_right, @parent_pos_right - @node_pos_right - 1, @parent_pos_right - @node_pos_right - 1 + @node_size),
Rgt = 0-(Rgt)+IF(@parent_pos_right > @node_pos_right, @parent_pos_right - @node_pos_right - 1, @parent_pos_right - @node_pos_right - 1 + @node_size)
WHERE Lft <= 0-@node_pos_left AND Rgt >= 0-@node_pos_right;
UPDATE ss_C_Categories
SET ParentID = @parent_id
WHERE CategoryID = @node_id;
执行查询后,这就是我的表格:
ID | Name | Rgt | Lft | ParentID
---+-------------+------+-----+---------
1 | Trousers | 1 | 2 | 0
---+-------------+------+-----+---------
2 | Jeans | 10 | 11 | 5
---+-------------+------+-----+---------
3 | Tops | 5 | 6 | 0
---+-------------+------+-----+---------
4 | T-shirts | 3 | 4 | 0
---+-------------+------+-----+---------
5 | Shirts | 7 | 8 | 0
---+-------------+------+-----+---------
我使用这个答案作为我如何做这些动作的灵感:https://stackoverflow.com/a/1274175/1308905
答案 0 :(得分:0)
好吧,现在我已经在很多绘图的帮助下创建了自己的MySQL,我认为这应该是方法,IF(仅在这种情况下): - 您将要将一个节点从一个父节点移动到另一个父节点。换句话说 - 不要用它来移动到“顶层”(尚未)。我还没有测试过它。
虽然将子树移动到另一个父级(无论新父级处于什么级别)都应该是防弹的。 : - )
$query = $this->prepare("
SELECT
@node_id := :nodeID, #id of the node, you're moving.
@node_pos_left := :nodeLeft, #left value of the node, you're moving
@node_pos_right := :nodeRight, #right value of the node, you're moving
@parent_id := :parentID, #id of the parent node, you're moving to
@parent_pos_right := :parentRight; #right value of the parent node, you're moving to.
SELECT
@node_size := @node_pos_right - @node_pos_left + 1;
SELECT
@node_id := :nodeID,
@node_pos_left := :nodeLeft,
@node_pos_right := :nodeRight,
@parent_id := :parentID,
@parent_pos_right := :parentRight;
SELECT
@node_size := @node_pos_right - @node_pos_left + 1;
UPDATE ss_C_Categories
SET Lft = 0-(Lft), Rgt = 0-(Rgt)
WHERE Lft >= @node_pos_left AND Rgt <= @node_pos_right;
UPDATE ss_C_Categories
SET Lft = Lft + @node_size
WHERE Lft >= @parent_pos_right;
UPDATE ss_C_Categories
SET Rgt = Rgt + @node_size
WHERE Rgt >= @parent_pos_right;
UPDATE ss_C_Categories
SET Lft = 0 - (Lft) + (@parent_pos_right - @node_pos_right + 1)
WHERE Lft < 0;
UPDATE ss_C_Categories
SET Rgt = 0 - (Rgt) + (@parent_pos_right - @node_pos_right + 1)
WHERE Rgt < 0;
UPDATE ss_C_Categories
SET Lft = Lft - @node_size
WHERE
Lft > @node_pos_right;
UPDATE ss_C_Categories
SET Rgt = Rgt - @node_size
WHERE
Rgt > @node_pos_right;
UPDATE
".DB_PREFIX."C_Categories
SET
CategoryName = :name,
MetaTag = :metatag,
ParentID = @parent_id,
Description = :desc
WHERE
CategoryID = @node_id
ORDER BY
CategoryID desc
LIMIT 1;
");
$params = array(
array('nodeLeft', $nodeLeft, 'INT'),
array('nodeRight', $nodeRight, 'INT'),
array('nodeID', $nodeID, 'INT'),
array('parentRight', $parentRight, 'INT'),
array('parentID', $parentID, 'INT'),
array('name', $data['name'], 'STR'),
array('metatag', $data['metatag'], 'STR'),
array('desc', $data['description'], 'STR')
);
$this->exec($query, $params);
再次从问题中的链接中获取灵感。