-- 3.5.63 Power
-- Вспом. функция, используется при конвертации линий
CREATE FUNCTION [Ограниченное_дерево_объекта] (@ObjectID int, @ObjectTypeIDs nvarchar(1024), @MaxLevel int = 100)
RETURNS @retObjs TABLE (id int, name nvarchar(200), ObjType int, ParentID int, Lev int, RowNum nvarchar(1000))
-- возвращает таблицу с кодами, именами и т.п. для объекта и его детей, Lev - уровень дерева,
-- RowNum - поле для упорядочивания, каждые5n символов содержат порядковый номер на уровне n
-- В таблицу попадает только сам объект (если его тип в списке) и его дети с типами из списка, 
-- если ребёнок другого типа - он и его поддерево не попадает в результат
-- список типов - через зпт.
AS
BEGIN
   DECLARE @RowsAdded int
   DECLARE @Level int
   IF @MaxLevel > 100 SET @MaxLevel = 100
   IF @MaxLevel < 1     SET @MaxLevel = 1
   SET @Level = 1
   -- таблица со списком допустимых типов
   DECLARE @ObjectTypes TABLE (ObjectTypeID int)
   INSERT @ObjectTypes
     SELECT * FROM dbo.StringToIntList(@ObjectTypeIDs, ',')
   -- таблица для накопления результата
   DECLARE @Objs TABLE (id int, name nvarchar(200), ObjType int, ParentID int, Lev int, RowNum nvarchar(1000))
   if @ObjectID <> 0 
     INSERT @Objs 
       SELECT Код_объекта, Наименование, Код_типа_объекта, Код_объекта_владельца, @Level, dbo.fn_IntAsString(Код_объекта) 
         FROM Объект WHERE Код_объекта = @ObjectID 
   else
     INSERT @Objs 
       SELECT Код_объекта, Наименование, Код_типа_объекта, Код_объекта_владельца, @Level, dbo.fn_IntAsString(Код_объекта) 
         FROM Объект WHERE Код_типа_объекта = 1000 AND Код_объекта_владельца IS NULL
   SET @RowsAdded = @@rowcount
   -- Повторять, пока что-то добавляется...
   WHILE (@RowsAdded > 0) AND (@Level < @MaxLevel)
   BEGIN
     -- Добавить объекты, дочерние для тех, у кого уровень = @Level
     INSERT @Objs
       SELECT Код_объекта, Наименование, Код_типа_объекта, Код_объекта_владельца, Lev+1, RowNum + dbo.fn_IntAsString(Код_объекта) 
         FROM Объект, @Objs, @ObjectTypes
         WHERE Код_объекта_владельца = id and Lev = @Level and ObjectTypeID = Код_типа_объекта
     SET @RowsAdded = @@rowcount
     SET @Level = @Level + 1 
   END   
   -- Копируем в результирующую таблицу, упорядочиваем по RowNum
   INSERT @retObjs
     SELECT Objs.* FROM @Objs Objs
     INNER JOIN @ObjectTypes ObjTypes ON ObjTypes.ObjectTypeID = ObjType
       ORDER BY RowNum
   RETURN
END