0

私は現在、解決できない問題に直面しています。すべてのカテゴリにネストされたセットを使用していますが、それらを移動する必要がある場合、何らかのバグがあります。私の問題は、ノードを移動したい場合です-たとえば、ID = 2を「トップレベル」からID = 1の下に置き、ID = 1 + Rgt = 2およびLft = 3でRgt = 1およびLft = 4を変更しますID=2 の場合、すべて動作します。

問題は、ID=2 のノードを最後のノード (ID=5、Rgt=9、Lft=10) に移動しようとすると、実際にテーブルが台無しになり、何が問題なのかわかりません。 mySQLクエリで-あなたが助けてくれることを願っています...

私のテーブルWHEN I STARTは次のようなものです:

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

4

1 に答える 1

0

さて、今、私は多くの図面の助けを借りて独自の MySQL を作成しました。これが進むべき道だと思います.IF (そしてまさにこの場合のみ): - 1 つの親からノードを移動します別の人に。言い換えれば、「トップレベル」に移動するためにこれを使用しないでください(まだ)。まだテストしていません。

サブツリーを別の親に移動することは防弾である必要がありますが(新しい親がどのレベルにあるかに関係なく)。:-)

$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);

再び、質問のリンクからインスピレーションを得て。

于 2013-10-01T18:16:10.203 に答える