Hej Du skulle kunna göra så här i en stored procedure (förutsatt att du inte har några luckor i nummerföljden NodeID, samt att valideringen av att noden verkligen får flyttas görs i GUI:t. Nedanstående SQL förutsätter att det finns en nod med NodeID som är ett lägre än den node man skickar in, dvs noden man skickar in får inte vara toppnod på sin nivå) : Om man drar en node och släpper den på önskad position skriver man på följande sätt:Komplicerad fråga.
Jag har en databas med en trädstruktur
ID ParentID NodeID
NodeID är ett tal som alla Noder får. Alla på samma nivå har ett stigande nummer.
Tex
Root (0)
underRoot(0)
underRoot(1)
enannanX(0)
enannanY(1)
underRoot(2)
Root2(1)
Jag har lagt in detta nummer för att man ska kunna flytta på en node upp och ner (inte i olika nivåer bara på sin egen nivå)
Hur ska jag göra detta. Måste ju köra någon update som om tex plussar på alla med ett. Ett problem är ju också om en nod är borttagen för då finns ju inte det nummert längre.
Tacksam för all hjälpSv: Komplicerad fråga.
<code>
CREATE PROCEDURE [dbo].MoveUp
@ID int
AS
SET NOCOUNT ON
DECLARE @ID2 int
DECLARE @Pos int
SELECT @Pos=[NodeID] FROM Project WHERE [ID]=@ID
SELECT @ID2=[ID] FROM Project WHERE [NodeID]=@Pos-1
-- Move the project
UPDATE Project SET [NodeID]=[NodeID]-1 WHERE [ID]=@ID
UPDATE Project SET [NodeID]=[NodeID]+1 WHERE [ID]=@ID2
GO
</code>
För att undvika hål vid borttag kan du göra följande :
<code>
CREATE PROCEDURE [dbo].DeleteNode
@ID int
AS
SET NOCOUNT ON
DECLARE @LoopID int
DECLARE @Pos int
DECLARE @ParentID int
SELECT @Pos=[NodeID] , @ParentID=[ParentID] FROM Project WHERE [ID]=@ID
DECLARE Project_Cursor CURSOR FOR
SELECT [ID] FROM Project
WHERE [ParentID]=@ParentID
AND [NodeID]>@Pos
ORDER BY [NodeID]
OPEN Project_Cursor
FETCH NEXT FROM Project_Cursor
INTO @LoopID
WHILE @@FETCH_STATUS=0
BEGIN
UPDATE Project SET [OrdinalPosition]=[OrdinalPosition]-1 WHERE [ID]=@LoopID
FETCH NEXT FROM Project_Cursor
INTO @LoopID
END
CLOSE Project_Cursor
DEALLOCATE Project_Cursor
-- Delete the node
DELETE FROM Project WHERE [ID]=@ID
GO
</code>
Ps. Byt ut alla Project mot ditt tabellnamn. Jag var tvungen att hitta på något och då blev det Project.Sv: Komplicerad fråga.
<code>
CREATE PROCEDURE ReplacePos
(
@FromID int
@ToID int
)
AS
DECLARE @NewPos int
DECLARE @NewParent int
DECLARE @OldPos int
DECLARE @OldParent int
/**
* Null ställer noden's position
**/
UPDATE TabellNamn SET @OldPos = TabellNamn.Pos,
@OldParent = TabellNamn.Parent,
TabellNamn.Pos = Null
WHERE TabellNamn.Id = @FromID
/**
* Hämtar ny position
**/
SELECT @NewPos = TabellNamn.Pos,
@NewParent = TabellNamn.Parent
FROM TabellNamn
WHERE TabellNamn.Id = @ToID
/**
* Flytta up noder som ligger mellan
**/
IF (@NewPos < @OldPos)
BEGIN
UPDATE TabellNamn SET TabellNamn.Pos = TabellNamn.Pos + 1
WHERE TabellNamn.Pos >= @NewPos AND TabellNamn.Pos <= @OldPos
END
/**
* Flytta ned noder som ligger mellan
**/
IF (@NewPos > @OldPos)
BEGIN
UPDATE TabellNamn SET TabellNamn.Pos = TabellNamn.Pos - 1
WHERE TabellNamn.Pos <= @NewPos AND TabellNamn.Pos >= @OldPos
END
/**
* Tilldelar noden sin nya position
**/
UPDATE TabellNamn SET TabellNamn.Pos = @NewPos
WHERE TabellNamn.Id = @FromID
GO
</code>
För att undvika hål vid borttag kan du göra följande :
<code>
CREATE PROCEDURE [dbo].DeleteNode
(
@ID int
)
AS
DECLARE @Pos int
DECLARE @ParentID int
/**
* Hämtar information om node
**/
SELECT @Pos = TabellNamn.Pos, @ParentID = TabellNamn.Parent
FROM TabellNamn
WHERE TabellNamn.ID = @ID
/**
* Tar bort node
**/
DELETE FROM TabellNamn
WHERE TabellNamn.ID = @ID
/**
* Flyttar upp efterliggande noder;
**/
UPDATE TabellNamn.Pos = TabellNamn.Pos - 1
WHERE TabellNamn.Parent = @ParentId AND TabellNamn.Pos >=@Pos
GO
</code>
Har ingen möklighet att testa. Ville bara visa en alternativt tillväga gångssätt.