Консоль и функция рекурсивного запроса

10.02.16

Разработка - Инструментарий разработчика

Консоль предназначена для отладки и просмотра результатов выполнения РЕКУРСИВНОГО ЗАПРОСА в режиме 1С:Предприятие.
В консоли реализована универсальная функция для выполнения рекурсивных запросов.

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Консоль РЕКУРСИВНОГО запроса для управляемого приложения
.epf 284,46Kb ver:0.0.1
12
12 Скачать (1 SM) Купить за 1 850 руб.

Рекурсивный запрос - удобный способ выборки иерархических данных. Примеры рекурсивной выборки данных в 1С:Предприятие подробно рассмотрены в "Запрос против рекурсии или разузлование номенклатуры", "Транзитивное замыкание запросом" или далее по ссылкам в публикациях. Авторы предложили три варианта решения проблемы бесконечной рекурсии в графах с циклическими ссылками:

  1. Ограничивать количество рекурсивных циклов, предварительно вычислив их максимально возможное значение;
  2. Исключать циклические ссылки, проверяя пройденный путь, сохраняя его в виде строки кодов вершин графа;
  3. Исключать циклические ссылки, проверяя пройденный путь, сохраняя его во временной таблице.

Консоль позволяет опробовать любой из трех вариантов, для этого в консоли реализована специальная функция ВыполнитьРекурсивныйЗапрос(...). В функцию собраны идеи, описанные в вышеупомянутых публикациях:

  • Рекурсивный запрос разбивается на три пакетных подзапроса: Начальный, Рекурсивный, Итоговый;
  • Рекурсивный подзапрос повторяется в цикле. Условие выхода из рекурсивного цикла отличается и описано в особенностях функции;
  • Начальные и промежуточные данные сохраняются во временные таблицы с индексом шага рекурсивного цикла;В тексте подзапросов к именам временных таблиц добавляются служебные окончания "__НАЧАЛО_РЕКУРСИИ__" или "__КОНЕЦ_РЕКУРСИИ__". Служебные окончания автоматически заменяются на соответствующий индекс шага рекурсивного цикла.

Встроенная в консоль функция имеет особенности:

  • В конце начального подзапроса возвращается количество начальных данных;
  • В конце рекурсивного подзапроса возвращается количество данных, отобранное для итоговой выборки;
  • Рекурсивный цикл повторяется до тех пор, пока возвращаемое подзапросом число (количество записей) оказывается больше предыдущего числа (количества записей) - полученного на предыдущем шаге рекурсивного цикла.
  • ВНИМАНИЕ! Не используйте в текстах Начального или Рекурсивного подзапросов стандартную функцию 1С:Предприятие ПРЕДСТАВЛЕНИЕ(), это приводит к бесконечной рекурсии - зависанию системы!
&НаСервере 
Функция ВыполнитьРекурсивныйЗапрос(ЗНАЧ Параметр, ЗНАЧ Значение
, ЗНАЧ ТекстЗапросаИтог
, ЗНАЧ ТекстЗапросаРекурсия
 , ЗНАЧ ТекстЗапросаНачало
 , ЗНАЧ ШагРекурсииНачало = "__НАЧАЛО_РЕКУРСИИ__" // Подменяется в тексте запроса на предыдущий индекс шага рекурсии
 , ЗНАЧ ШагРекурсииКонец = "__КОНЕЦ_РЕКУРСИИ__" // Подменяется в тексте запроса на текущий индекс шага рекурсии
 , ЗНАЧ ЗапросМаксимальноеКоличествоЗаписей = "ВЫБРАТЬ 0;" // для предотвращения бесконечных рекурсий, 0 - без ограничений
, ЗНАЧ РежимОтладки = Ложь ) Экспорт

    Если СокрЛП(ШагРекурсииНачало)="" тогда
        ШагРекурсииНачало = "__НАЧАЛО_РЕКУРСИИ__"
    КонецЕсли;

    Если
СокрЛП(ШагРекурсииКонец)="" тогда
        ШагРекурсииКонец = "__КОНЕЦ_РЕКУРСИИ__"
    КонецЕсли; ТекВремя = ТекущаяДата();

    Если РежимОтладки тогда
        Сообщить(Формат(ТекВремя, "ДЛФ=T") + ", СТАРТ запроса",СтатусСообщения.Информация);
    КонецЕсли;

    Запрос = Новый Запрос();
 
    // Менеджер временных таблиц необходим для сохранения в памяти промежуточных таблиц рекурсии

    Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц();

    // ИндексРекурсии для генерации шага рекурсии в имени таблицы
    ИндексРекурсии = 0;

    // Если начальный запрос пустой, выполним только итоговый запрос

    Если ТекстЗапросаНачало<>Неопределено И ТекстЗапросаНачало<>"" тогда

        // Выход из рекурсии, когда количество записей в итоговой теблице перестанет прибавляться

        СтароеКоличествоЗаписей = 0;
        НовоеКоличествоЗаписей = 0;

        // Заменим в начальном подзапросе имена таблиц, указав начальный шаг рекрсии
        Запрос.Текст = СтрЗаменить(ТекстЗапросаНачало, ШагРекурсииНачало, Формат(ИндексРекурсии, "ЧН=0; ЧГ=0"));

        Если Параметр<>Неопределено И Параметр<>"" тогда
            Запрос.УстановитьПараметр(Параметр, Значение);
        КонецЕсли;

        // Выполним начальный подзапрос
        Попытка РезультатЗапроса = Запрос.Выполнить();
            Исключение ВызватьИсключение "Ошибка в НАЧАЛЬНОМ подзапросе: " + ОписаниеОшибки() + " !ВНИМАНИЕ! Ключевое слово '"+ШагРекурсииНачало+"' заменено на '"+Формат(ИндексРекурсии, "ЧН=0; ЧГ=0")+"'";
        КонецПопытки
;

        // Если рекурсивный запрос пустой, выполним только итоговый запрос
        Если ТекстЗапросаРекурсия<>Неопределено И ТекстЗапросаРекурсия<>"" тогда

            // Определим указанное в парамтрах максимальное допустимое количество шагов рекурсивного подзапроса
            МаксимальноеКоличествоРекурсий=0;

            Если ЗапросМаксимальноеКоличествоЗаписей<>Неопределено И ЗапросМаксимальноеКоличествоЗаписей<>"" тогда
                ЗапросКоличества = Новый Запрос();
                ЗапросКоличества.Текст = ЗапросМаксимальноеКоличествоЗаписей;

                Попытка

                    РезультатЗапросаКоличества = ЗапросКоличества.Выполнить();
                    ВыборкаДетальныеЗаписи = РезультатЗапросаКоличества.Выбрать();

                    Если ВыборкаДетальныеЗаписи.Следующий() Тогда
                   
                        МаксимальноеКоличествоРекурсий = ВыборкаДетальныеЗаписи.Получить(0);
                   
                        Если ТипЗнч(МаксимальноеКоличествоРекурсий)<>Тип("Число") тогда
                            Сообщить("Запрос '"+ЗапросМаксимальноеКоличествоЗаписей+"' для ограничения максимального количества записей должен быть пустым, либо возвращать число!" ,СтатусСообщения.Внимание);
                            МаксимальноеКоличествоРекурсий=1;
                        КонецЕсли;
                    КонецЕсли;
                Исключение
                    Сообщить("Запрос для ограничения максимального количества записей рекурсии выполнен с ошибкой:" + ОписаниеОшибки() ,СтатусСообщения.Внимание);
                    МаксимальноеКоличествоРекурсий=1;
                КонецПопытки
;
            КонецЕсли;

            // Определим количество записей полученное в начальном подзапросе
            ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();

            Если
ВыборкаДетальныеЗаписи.Следующий() Тогда
           
                НовоеКоличествоЗаписей = ВыборкаДетальныеЗаписи.Получить(0);
           
                Если
ТипЗнч(НовоеКоличествоЗаписей)<>Тип("Число") тогда
                    Сообщить("Начальный подзапрос должен возвращать количество записей в начальной выборке! НАПРИМЕР: 'ВЫБРАТЬ КОЛИЧЕСТВО (*) ИЗ ИтоговаяТаблица"+ШагРекурсииНачало+"' " ,СтатусСообщения.Внимание);
                    НовоеКоличествоЗаписей=1;
                КонецЕсли;
            КонецЕсли;

            Если РежимОтладки тогда
                ТекВремя=ТекущаяДата();
                Сообщить(Формат(ТекВремя, "ДЛФ=T") + ", выполнен НАЧАЛЬНЫЙ подзапрос, количество записей: "+НовоеКоличествоЗаписей,СтатусСообщения.Информация);
            КонецЕсли
;

            // Основной Ц И К Л рекурсии, пока увеличивается количество записей
            Пока НовоеКоличествоЗаписей > СтароеКоличествоЗаписей
                И (МаксимальноеКоличествоРекурсий=0 ИЛИ НовоеКоличествоЗаписей < МаксимальноеКоличествоРекурсий) цикл

                // Сдвигаем количество записей и индекс рекурсии
                СтароеКоличествоЗаписей = НовоеКоличествоЗаписей;
                ИндексРекурсии = ИндексРекурсии + 1;

                // Заменим в рекурсивном подзапросе имена таблиц, указав текущий шаг рекрсии

                Запрос.Текст = СтрЗаменить(ТекстЗапросаРекурсия, ШагРекурсииНачало, Формат(ИндексРекурсии-1, "ЧН=0; ЧГ=0"));
                Запрос.Текст = СтрЗаменить(Запрос.Текст, ШагРекурсииКонец, Формат(ИндексРекурсии, "ЧН=0; ЧГ=0"));

                Если
Параметр<>Неопределено И Параметр<>"" тогда
                    Запрос.УстановитьПараметр(Параметр, Значение);
                КонецЕсли;

                // Выполним рекурсивный подзапрос
                Попытка
                    РезультатЗапроса = Запрос.Выполнить();
                Исключение
                    ВызватьИсключение "Ошибка в РЕКУРСИВНОМ подзапросе: " + ОписаниеОшибки() + " !ВНИМАНИЕ! Ключевые слова: '"+ШагРекурсииНачало+"' заменено на '"+Формат(ИндексРекурсии-1, "ЧН=0; ЧГ=0")+"', " + " '"+ШагРекурсииКонец+"' заменено на '"+Формат(ИндексРекурсии, "ЧН=0; ЧГ=0")+"'";
                КонецПопытки
;

                ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();

                // Определим новое количество записей, полученное в рекурсивном подзапросе
                Если ВыборкаДетальныеЗаписи.Следующий() Тогда
               
                    НовоеКоличествоЗаписей = ВыборкаДетальныеЗаписи.Получить(0);

                    Если ТипЗнч(НовоеКоличествоЗаписей)<>Тип("Число") тогда
                        Сообщить("Рекурсивный подзапрос должен возвращать количество записей в итоговой выборке! НАПРИМЕР: 'ВЫБРАТЬ КОЛИЧЕСТВО (*) ИЗ ИтоговаяТаблица"+ШагРекурсииНачало+"' " ,СтатусСообщения.Внимание);
                        НовоеКоличествоЗаписей=1;
                    КонецЕсли;
                КонецЕсли;

                Если РежимОтладки И ТекВремя<>ТекущаяДата() тогда
                    ТекВремя=ТекущаяДата();
                    Сообщить(Формат(ТекВремя, "ДЛФ=T") + ", выполнен " + ИндексРекурсии + " РЕКУРСИВНЫЙ подзапрос, количество записей: "+НовоеКоличествоЗаписей,СтатусСообщения.Информация);
                КонецЕсли
;
           
            КонецЦикла
;
       
        КонецЕсли
;
    КонецЕсли;

    // Заменим в итоговом подзапросе имена таблиц, указав конечный шаг рекрсии
    Запрос.Текст = СтрЗаменить(ТекстЗапросаИтог, ШагРекурсииКонец, Формат(ИндексРекурсии, "ЧН=0; ЧГ=0"));

    Если Параметр<>Неопределено И Параметр<>"" тогда
        Запрос.УстановитьПараметр(Параметр, Значение);
    КонецЕсли
;

    // Выполним итоговый подзапрос
    Попытка
        РезультатЗапроса = Запрос.Выполнить();
    Исключение
        ВызватьИсключение "Ошибка в ИТОГОВОМ подзапросе: " + ОписаниеОшибки() + " !ВНИМАНИЕ! Ключевое слово '"+ШагРекурсииКонец+"' заменено на '"+Формат(ИндексРекурсии, "ЧН=0; ЧГ=0")+"'";
    КонецПопытки
;

    Если
РежимОтладки тогда ТекВремя=ТекущаяДата();
        Сообщить(Формат(ТекВремя, "ДЛФ=T") + ", выполнен ИТОГОВЫЙ подзапрос",СтатусСообщения.Информация);
    КонецЕсли;

    Возврат РезультатЗапроса;
КонецФункции

Консоль выполняет рекурсивный запрос в одном из двух режимов:

  • “Выполнить” - в стандартном режиме;
  • “Выполнить запрос с указанием времени” - с указанием времени выполнения рекурсивного запроса в формате часы:минуты:секунды.

Пример тестовой таблицы (вставить перед начальным подзапросом)

/////////////////////////////////////////////////////////////////////////////// 
// ФОРМИРОВАНИЕ ТЕСТОВОЙ ТАБЛИЦЫ

ВЫБРАТЬ 0 КАК объект, 1 КАК субъект , "00" КАК с_объект, "01" КАК с_субъект
ПОМЕСТИТЬ таблица10
ОБЪЕДИНИТЬ ВЫБРАТЬ 0 КАК объект, 2 КАК субъект , "00" КАК с_объект, "02" КАК с_субъект
ОБЪЕДИНИТЬ ВЫБРАТЬ 0 КАК объект, 3 КАК субъект , "00" КАК с_объект, "03" КАК с_субъект
ОБЪЕДИНИТЬ ВЫБРАТЬ 0 КАК объект, 4 КАК субъект , "00" КАК с_объект, "04" КАК с_субъект
ОБЪЕДИНИТЬ
ВЫБРАТЬ 0 КАК объект, 5 КАК субъект , "00" КАК с_объект, "05" КАК с_субъект
ОБЪЕДИНИТЬ ВЫБРАТЬ 0 КАК объект, 6 КАК субъект , "00" КАК с_объект, "06" КАК с_субъект
ОБЪЕДИНИТЬ
ВЫБРАТЬ 0 КАК объект, 7 КАК субъект , "00" КАК с_объект, "07" КАК с_субъект
ОБЪЕДИНИТЬ
ВЫБРАТЬ 0 КАК объект, 8 КАК субъект , "00" КАК с_объект, "08" КАК с_субъект
ОБЪЕДИНИТЬ ВЫБРАТЬ 0 КАК объект, 9 КАК субъект , "00" КАК с_объект, "09" КАК с_субъект
ОБЪЕДИНИТЬ ВЫБРАТЬ 0 КАК объект, 10 КАК субъект , "00" КАК с_объект, "10" КАК с_субъект;

ВЫБРАТЬ 100+родитель.субъект КАК объект, 200+потомок.субъект КАК субъект
,
"1"+родитель.с_субъект КАК с_объект, "2"+потомок.с_субъект КАК с_субъект
ПОМЕСТИТЬ
таблица100 ИЗ таблица10 КАК родитель, таблица10 КАК потомок;

ВЫБРАТЬ 200+родитель.субъект КАК объект, 300+потомок.субъект КАК субъект
, "2"+родитель.с_субъект КАК с_объект, "3"+потомок.с_субъект КАК с_субъект
ПОМЕСТИТЬ таблица1000 ИЗ таблица10 КАК родитель, таблица10 КАК потомок;

ВЫБРАТЬ 300+родитель.субъект КАК объект, 400+потомок.субъект КАК субъект
, "3"+родитель.с_субъект КАК с_объект, "4"+потомок.с_субъект КАК с_субъект
ПОМЕСТИТЬ
таблица10000 ИЗ таблица10 КАК родитель, таблица10 КАК потомок;

ВЫБРАТЬ
400+родитель.субъект КАК объект, 500+потомок.субъект КАК субъект
,
"4"+родитель.с_субъект КАК с_объект, "5"+потомок.с_субъект КАК с_субъект
ПОМЕСТИТЬ таблица100000 ИЗ таблица10 КАК родитель, таблица10 КАК потомок;

ВЫБРАТЬ 500+родитель.субъект КАК объект, 600+потомок.субъект КАК субъект
,
"5"+родитель.с_субъект КАК с_объект, "6"+потомок.с_субъект КАК с_субъект
ПОМЕСТИТЬ
таблица1000000 ИЗ таблица10 КАК родитель, таблица10 КАК потомок;

ВЫБРАТЬ
000+объект КАК объект, 100+субъект КАК субъект , "0"+с_объект КАК с_объект
,
"1"+с_субъект КАК с_субъект ПОМЕСТИТЬ таблица ИЗ таблица10
ОБЪЕДИНИТЬ
ВСЕ ВЫБРАТЬ * ИЗ таблица100
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ * ИЗ таблица1000
ОБЪЕДИНИТЬ
ВСЕ ВЫБРАТЬ * ИЗ таблица10000
ОБЪЕДИНИТЬ
ВСЕ ВЫБРАТЬ ПЕРВЫЕ 0 * ИЗ таблица100000
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ ПЕРВЫЕ 0 * ИЗ таблица1000000

// Циклическая ссылка

//0// ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 301 КАК объект, 101 КАК субъект
//0// , "301" КАК с_объект, "101" КАК с_субъект

ИНДЕКСИРОВАТЬ ПО объект, субъект;

УНИЧТОЖИТЬ
таблица10;
УНИЧТОЖИТЬ таблица100;
УНИЧТОЖИТЬ таблица1000;
УНИЧТОЖИТЬ таблица10000;
УНИЧТОЖИТЬ таблица100000;
УНИЧТОЖИТЬ таблица1000000;

// КОНЕЦ ФОРМИРОВАНИЯ ТЕСТОВОЙ ТАБЛИЦЫ
///////////////////////////////////////////////////////////////////////////////

Пример начального подзапроса

/////////////////////////////////////////////////////////////////////////////// 
// НАЧАЛЬНЫЙ ПОДЗАПРОС

ВЫБРАТЬ
объект, субъект , с_объект, с_субъект
, 1 КАК уровень , "."+с_объект+"."+с_субъект+"." КАК путь
, "" КАК старый_путь
ПОМЕСТИТЬ РекурсивнаяТаблица__НАЧАЛО_РЕКУРСИИ__
ИЗ таблица
ГДЕ
объект=0;

//--------- служебная счасть ---------//


// 1.1. ПРОЙДЕННЫЕ УЗЛЫ
// для исключения бесконечной рекурсии
//3//ВЫБРАТЬ РАЗЛИЧНЫЕ объект, субъект
//3//ПОМЕСТИТЬ ПройденныеУзлы__НАЧАЛО_РЕКУРСИИ__
//3//ИЗ РекурсивнаяТаблица__НАЧАЛО_РЕКУРСИИ__

//3//ОБЪЕДИНИТЬ
//3//ВЫБРАТЬ субъект КАК объект, субъект
//3//ИЗ РекурсивнаяТаблица__НАЧАЛО_РЕКУРСИИ__

//3//ИНДЕКСИРОВАТЬ ПО 2,1;


// 1.2. ИТОГОВЫЕ ДАННЫЕ
ВЫБРАТЬ * ПОМЕСТИТЬ ИтоговаяТаблица__НАЧАЛО_РЕКУРСИИ__
ИЗ РекурсивнаяТаблица__НАЧАЛО_РЕКУРСИИ__;

// 1.4. КОЛИЧЕСТВО ЗАПИСЕЙ

ВЫБРАТЬ КОЛИЧЕСТВО(*) ИЗ ИтоговаяТаблица__НАЧАЛО_РЕКУРСИИ__;

// КОНЕЦ НАЧАЛЬНОГО ПОДЗАПРОСА
///////////////////////////////////////////////////////////////////////////////

Пример рекурсивного подзапроса

/////////////////////////////////////////////////////////////////////////////// 
// РЕКУРСИВНЫЙ ПОДЗАПРОС


ВЫБРАТЬ таблица.*, рекурсия.уровень+1 КАК уровень
, рекурсия.путь+таблица.с_субъект+"." КАК путь
,
рекурсия.путь КАК старый_путь
ПОМЕСТИТЬ РекурсивнаяТаблица__КОНЕЦ_РЕКУРСИИ__
ИЗ РекурсивнаяТаблица__НАЧАЛО_РЕКУРСИИ__ КАК рекурсия
ВНУТРЕННЕЕ СОЕДИНЕНИЕ
таблица ПО таблица.объект=рекурсия.субъект

// соединенние для исключения бесконечной рекурсии
//3//ЛЕВОЕ СОЕДИНЕНИЕ ПройденныеУзлы__НАЧАЛО_РЕКУРСИИ__ ПройденныеУзлы
//3// ПО ПройденныеУзлы.субъект=таблица.объект
//3// И ПройденныеУзлы.объект=таблица.субъект
ГДЕ ИСТИНА
//1// И рекурсия.уровень<8 // ограниечение количества уровней //2// И НЕ рекурсия.путь ПОДОБНО "%."+таблица.с_субъект+".%" //3// И ПройденныеУзлы.субъект ЕСТЬ NULL ;

//--------- служебная счасть ---------//
// 2.1. ПРОЙДЕННЫЕ УЗЛЫ
// для исключения бесконечной рекурсии //3//ВЫБРАТЬ РАЗЛИЧНЫЕ ПройденныеУзлы.объект, Рекурсия.субъект //3//ПОМЕСТИТЬ ПройденныеУзлы__КОНЕЦ_РЕКУРСИИ__ //3//ИЗ РекурсивнаяТаблица__КОНЕЦ_РЕКУРСИИ__ Рекурсия //3//ВНУТРЕННЕЕ СОЕДИНЕНИЕ ПройденныеУзлы__НАЧАЛО_РЕКУРСИИ__ ПройденныеУзлы ПО ПройденныеУзлы.субъект=Рекурсия.объект //3//ОБЪЕДИНИТЬ //3//ВЫБРАТЬ субъект КАК объект, субъект ИЗ РекурсивнаяТаблица__КОНЕЦ_РЕКУРСИИ__ //3//ИНДЕКСИРОВАТЬ ПО 2,1;
// 2.2. ИТОГОВЫЕ ДАННЫЕ ВЫБРАТЬ * ПОМЕСТИТЬ ИтоговаяТаблица__КОНЕЦ_РЕКУРСИИ__ ИЗ ИтоговаяТаблица__НАЧАЛО_РЕКУРСИИ__
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ * ИЗ РекурсивнаяТаблица__КОНЕЦ_РЕКУРСИИ__ ;

// 2.3. ОСВОБОЖДЕНИЕ ПАМЯТИ
//3//УНИЧТОЖИТЬ ПройденныеУзлы__НАЧАЛО_РЕКУРСИИ__;
УНИЧТОЖИТЬ
РекурсивнаяТаблица__НАЧАЛО_РЕКУРСИИ__;
УНИЧТОЖИТЬ ИтоговаяТаблица__НАЧАЛО_РЕКУРСИИ__;

// 2.4. КОЛИЧЕСТВО ЗАПИСЕЙ

ВЫБРАТЬ КОЛИЧЕСТВО(*) ИЗ ИтоговаяТаблица__КОНЕЦ_РЕКУРСИИ__;

// КОНЕЦ РЕКУРСИВНОГО ПОДЗАПРОСА
///////////////////////////////////////////////////////////////////////////////

Пример итогового подзапроса

/////////////////////////////////////////////////////////////////////////////// 
// ИТОГОВЫЙ ПОДЗАПРОС

ВЫБРАТЬ //ПЕРВЫЕ 10
КОЛИЧЕСТВО(*)
// *
ИЗ ИтоговаяТаблица__КОНЕЦ_РЕКУРСИИ__
//УПОРЯДОЧИТЬ ПО объект, субъект, путь
;

//--------- служебная счасть ---------//
// 3.3. ОСВОБОЖДЕНИЕ ПАМЯТИ
//3//УНИЧТОЖИТЬ ПройденныеУзлы__КОНЕЦ_РЕКУРСИИ__;
УНИЧТОЖИТЬ РекурсивнаяТаблица__КОНЕЦ_РЕКУРСИИ__;
УНИЧТОЖИТЬ ИтоговаяТаблица__КОНЕЦ_РЕКУРСИИ__;
УНИЧТОЖИТЬ таблица;

// конец ИТОГОВЫЙ ПОДЗАПРОС
///////////////////////////////////////////////////////////////////////////////

В подзапросах отмечены комментариями:
//0// - пример циклической ссылки - ВНИМАНИЕ! Возможно зависание системы! Не убирайте данный комментарий, если в рекурсивный запрос не включен механизм исключения циклических ссылок.
//1// - пример ограничения количества шагов рекурсивного цикла.
//2// - пример исключения циклических ссылок через проверку пройденного пути сохраненного в виде строки кодов вершин графа.
//3// - (в разных местах запроса) пример исключения циклических ссылок через проверку пройденного пути сохраненного во временную таблицу.

Время работы рекурсивной выборки в зависимости от количества итоговых записей

Тест файловой СУБД, Core2Duo 2.40GHz, 4ГБ ОЗУ

 Файл-серверная статистика

Кол-во

  записей 

 Время выполнение рекурсивного

запроса (сек.)

Без

 контроля

 Контроль и сохранение

пройденного пути

в строке в таблице
111 110 5 6 37
121 110 6 7 43
211 110 10 11 81
311 110 15 16 124
411 110 20 21 172
511 110 23 25 211
711 110 32 35 257
911 110 41 44 385
 1 111 110
49 54 473


Тест на http://demo.1c.ru

 Тест на demo.1c.ru

 

Кол-во

  записей 

 Время выполнение рекурсивного

запроса (сек.)

Без

 контроля

 Контроль и сохранение

пройденного пути

в строке в таблице
111 110 1 2 7
121 110 1 2 7
211 110 1 4 9
311 110 3 5 9
411 110 3 6 11
511 110 4 7 12
711 110 5 9 15
911 110 10 11 17
 1 111 110
11 11 20

 

 

 

 

 

рекурсия запрос консоль

См. также

Инструментарий разработчика Роли и права Запросы СКД Программист Руководитель проекта Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Платные (руб)

Инструменты для разработчиков 1С 8.3: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

15500 руб.

02.09.2020    179994    999    403    

954

Инструментарий разработчика Чистка данных Свертка базы Инструменты администратора БД Системный администратор Программист Руководитель проекта Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 Россия Платные (руб)

Инструмент представляет собой обработку для проведения свёртки или обрезки баз данных. Работает на ЛЮБЫХ конфигурациях (УТ, БП, ERP, УНФ, КА и т.д.). Поддерживаются серверные и файловые базы, управляемые и обычные формы. Может выполнять свертку одновременно в несколько потоков. А так же автоматически, без непосредственного участия пользователя. Решение в Реестре отечественного ПО

8400 руб.

20.08.2024    21437    140    80    

142

Пакетная печать Печатные формы Инструментарий разработчика Программист Платформа 1С v8.3 Запросы 1С:Зарплата и кадры бюджетного учреждения 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 Платные (руб)

Инструмент, позволяющий абсолютно по-новому взглянуть на процесс разработки печатных форм. Благодаря конструктору можно значительно снизить затраты времени на разработку печатных форм, повысить качество и "прозрачность" разработки, а также навести порядок в многообразии корпоративных печатных форм.

22200 руб.

06.10.2023    19377    51    19    

84

Инструменты администратора БД Инструментарий разработчика Роли и права Программист Платформа 1С v8.3 1C:Бухгалтерия Россия Платные (руб)

Расширение позволяет без изменения кода конфигурации выполнять проверки при вводе данных, скрывать от пользователя недоступные ему данные, выполнять код в обработчиках. Не изменяет данные конфигурации, легко устанавливается практически на любую конфигурацию на управляемых формах.

15000 руб.

10.11.2023    13151    55    33    

73

Инструментарий разработчика Программист Платформа 1С v8.3 Платные (руб)

Инструмент для написания и отладки кода в режиме «1С:Предприятие». Представляет собой консоль кода с возможностью пошаговой отладки, просмотра значений переменных любых типов, использования процедур и функций, просмотра стека вызовов, вычисления произвольных выражений на встроенном языке в контексте точки останова, синтаксического контроля и остановки по ошибке. В консоли используется удобный редактор кода с подсветкой, контекстной подсказкой, возможностью вызова конструкторов запроса и форматной строки.

9360 руб.

17.05.2024    29476    101    48    

147

Инструментарий разработчика Программист 8.3.14 Россия Платные (руб)

Расширение для конфигурации “Конвертация данных 3”. Добавляет подсветку синтаксиса, детальную контекстную подсказку, глобальный поиск по коду.

20000 руб.

07.10.2021    18791    7    32    

43

Инструментарий разработчика Платформа 1С v8.3 1C:Бухгалтерия 1С:ERP Управление предприятием 2 Платные (руб)

Разработка Конструктор автоматизированных рабочих мест "Конструктор АРМ" реализована в виде расширения и является универсальным инструментом для создания АРМ любой сложности в пользовательском режиме.

3600 руб.

27.12.2024    1930    2    0    

6
Оставьте свое сообщение