Есть несколько изменений, которые вы можете сделать, чтобы заставить это работать.Во-первых, вам не нужен oldPath
, представляющий родителя узла, который вы хотите переместить.В функции .GetReparentedValue
вы помещаете иерархию движущегося узла, которая является значением в path
.
Вторым изменением является добавление еще одного оператора SELECT для применения вашей функции GetDescendant
.Вот пример сценария, который вы можете попробовать в SQL Server Management Studio (SSMS) или изменить, чтобы включить его в вызовы SQLCommand.Первые несколько строк (объявления переменных являются присваиваниями) предназначены только для работы в SSMS.Вы должны перенести последние операторы SELECT
и UPDATE
в вызывающий код.
DECLARE @Path hierarchyid
DECLARE @oldPath hierarchyid
DECLARE @newPath hierarchyid
SELECT @Path=0x58, @oldPath=0x, @newPath=0x68
SELECT @newPath = @newPath.GetDescendant(MAX(Path), NULL)
FROM Structure
WHERE path.GetAncestor(1)=@newPath;
UPDATE Structure
SET Path = Path.GetReparentedValue(@Path, @newPath)
WHERE Path = @Path;
Ваш оператор UPDATE
, и эта редакция будет переопределять только один узел.Он не будет автоматически перемещать дочерние элементы движущегося узла.Дочерние элементы движущегося узла будут осиротевшими.
Если вам нужно переместить выбранный узел и всех потомков этого узла, вы можете использовать следующий вариант предыдущих операторов.
DECLARE @Path hierarchyid
DECLARE @oldPath hierarchyid
DECLARE @newPath hierarchyid
SELECT @Path=0x58, @oldPath=0x, @newPath=0x68
SELECT @newPath = @newPath.GetDescendant(MAX(Path), NULL)
FROM Structure
WHERE Path.GetAncestor(1) = @newPath ;
UPDATE Structure
SET Path = Path.GetReparentedValue(@Path, @newPath)
WHERE Path.IsDescendantOf(@Path) = 1;
Фактически, единственное изменение от первого сценария к этому сценарию - в самой последней строке.Тест Path.IsDescendantOf(@Path) = 1
верен для всех потомков @Path
, включая @Path
.Иерархические отношения будут поддерживаться после обновления.