Хранимая процедура, обновляющая уровни иерархии в любой иерархической таблице
CREATE PROCEDURE UpdateHierarchyLevels @TableName SfaString, @IdColumnName SfaString AS ——————————————————— — Описание: — Обновление значений уровня иерархии в стандартной иерархической таблице. — Параметры: — @TableName - имя таблицы, в которой проводятся обновления. — @IdColumnName - имя столбца с идентификатором строки, на который ссылается ParentId ——————————————————— SET nocount ON DECLARE @SqlStr AS varchar(8000) — Сначала очистка уровней иерархии, чтобы были изменения — на каждом шаге итерации. SELECT @SqlStr = ?UPDATE ? + @TableName + ? SET HierarchyLevel = 0 ? EXEC (@SqlStr) — Установка уровня иерархии самого верхнего элемента. — У самого верхнего элемента родитель не определен, IS NULL. SELECT @SqlStr = ?UPDATE ?+ @TableName + ? SET HierarchyLevel = 1 ? + ? WHERE ParentId IS NULL? EXEC (@SqlStr) — Итеративное задание уровней иерархии для дочерних элементов. — Дочерним является такой элемент, у которого родитель входит в — множество записей текущего уровня иерархии. — Задание для них уровня иерархии равным текущему уровню + 1. — Провести итерацию, если были сделаны изменения. DECLARE @CurrentHierarchyLevel _ AS smallint DECLARE @NumOfRecordsUpdated AS int SELECT @CurrentHierarchyLevel = 1 SELECT @NumOfRecordsUpdated = 1 — Проверка начала итерации WHILE ((@CurrentHierarchyLevel < 255) — Проверка отсутствия бесконечного цикла AND (@NumOfRecordsUpdated > 0)) — Прекращение итераций при отсутствии изменений BEGIN SELECT @SqlStr = ?UPDATE TChild ? + ? SET HierarchyLevel = ? + _ CONVERT(varchar(10), _ @CurrentHierarchyLevel _ + 1) + ? FROM ? + @TableName + ? TChild, ?_ @TableName + _ ?TParent? + ? WHERE TChild.ParentId = TParent.? _ + @IdColumnName + ? AND TParent.HierarchyLevel = ?_ + CONVERT(varchar(10), _ @CurrentHierarchyLevel) EXEC (@SqlStr) SELECT @NumOfRecordsUpdated = _ @@RowCount — Получение количества измененных записей SELECT @CurrentHierarchyLevel = _ @CurrentHierarchyLevel + 1 END — WHILE SET nocount OFF