Move node in nested set

后端 未结 13 1037
孤街浪徒
孤街浪徒 2020-12-07 15:06

I\'d need a MySQL query that moves a node and all its children within a nested set. I found this site, but that function just seems so illogical - there\'s no universe

13条回答
  •  广开言路
    2020-12-07 15:28

    I know this is an old question, but I've just used the answer myself but for SQL Server. Should anyone want it, here is the code for a SQL Server Stored Proc based on the accepted answer.

    CREATE PROCEDURE [dbo].[Item_Move] 
        @id uniqueidentifier, 
        @destinationId uniqueidentifier
    AS
    BEGIN
    
        SET NOCOUNT ON;
    
        declare @moverLeft int,
                @moverRight int,
                @destinationRight int,
                @node_size int
    
        -- step 0: Initialize parameters.
        SELECT 
            @moverLeft = leftExtent, 
            @moverRight = rightExtent 
        FROM 
            Item 
        WHERE 
            id = @id
    
        SELECT 
            @destinationRight = rightExtent 
        FROM 
            Item 
        WHERE 
            id = @destinationId
    
        SELECT
            @node_size = @moverRight - @moverLeft + 1; -- 'size' of moving node (including all it's sub nodes)
    
        -- step 1: temporary "remove" moving node
        UPDATE Item
        SET leftExtent = 0-(leftExtent), rightExtent = 0-(rightExtent), updatedDate = GETDATE()
        WHERE leftExtent >= @moverLeft AND rightExtent <= @moverRight;
    
        -- step 2: decrease left and/or right position values of currently 'lower' items (and parents)
        UPDATE Item
        SET leftExtent = leftExtent - @node_size, updatedDate = GETDATE()
        WHERE leftExtent > @moverRight;
        UPDATE Item
        SET rightExtent = rightExtent - @node_size, updatedDate = GETDATE()
        WHERE rightExtent > @moverRight;
    
        -- step 3: increase left and/or right position values of future 'lower' items (and parents)
        UPDATE Item
        SET leftExtent = leftExtent + @node_size, updatedDate = GETDATE()
        WHERE leftExtent >= CASE WHEN @destinationRight > @moverRight THEN @destinationRight - @node_size ELSE @destinationRight END;
        UPDATE Item
        SET rightExtent = rightExtent + @node_size, updatedDate = GETDATE()
        WHERE rightExtent >= CASE WHEN @destinationRight > @moverRight THEN @destinationRight - @node_size ELSE @destinationRight END;
    
        -- step 4: move node (and it's subnodes) and update it's parent item id
        UPDATE Item
        SET
            leftExtent = 0-(leftExtent) + CASE WHEN @destinationRight > @moverRight THEN @destinationRight - @moverRight - 1 ELSE @destinationRight - @moverRight - 1 + @node_size END,
            rightExtent = 0-(rightExtent) + CASE WHEN @destinationRight > @moverRight THEN @destinationRight - @moverRight - 1 ELSE @destinationRight - @moverRight - 1 + @node_size END, 
            updatedDate = GETDATE()
        WHERE leftExtent <= 0-@moverLeft AND rightExtent >= 0-@moverRight;
        UPDATE Item
        SET parentId = @destinationId, updatedDate = GETDATE()
        WHERE id = @id;
    
    
    END
    

提交回复
热议问题