При работе со сложными запросами в 1С часто возникает необходимость не просто получить финальный результат, но и обработать промежуточные данные, которые находятся во временных таблицах (ВТ). По умолчанию временная таблица существует только внутри сессии выполнения запроса, но платформой предусмотрены механизмы, позволяющие «продлить ей жизнь» и даже выгрузить ее содержимое в ТаблицаЗначений для дальнейшего анализа в коде. Рассмотрим подробнее, как это реализовать.
Проанализируем самый гибкий и универсальный способ — использование специального объекта МенеджерВременныхТаблиц. Этот объект выступает в роли контейнера для ВТ и позволяет им существовать между вызовами различных запросов. Для того чтобы извлечь данные, нам необходимо выполнить следующие шаги:
ПолучитьДанные() менеджера для извлечения нужной таблицы.Рассмотрим пример кода:
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Товар
|ПОМЕСТИТЬ ВТ_Товары
|ИЗ
| Справочник.Номенклатура КАК Номенклатура";
// Выполняем запрос для наполнения менеджера данными
Запрос.Выполнить();
// Извлекаем данные конкретной таблицы в Таблицу Значений
ТЗ_Товары = Запрос.МенеджерВременныхТаблиц.Таблицы.Найти("ВТ_Товары").ПолучитьДанные().Выгрузить();
Важно помнить, что МенеджерВременныхТаблиц потребляет ресурсы СУБД (например, место в tempdb для SQL Server). Поэтому хорошим тоном считается использование метода Закрыть() или команды запроса УНИЧТОЖИТЬ, когда данные больше не нужны.
Выясним причину популярности этого метода. Он идеально подходит для отладки или случаев, когда вам нужно получить результаты всех таблиц пакета сразу. В отличие от стандартного метода ВыполнитьПакет(), который возвращает только результаты финальных выборок и количество строк в ВТ, этот метод возвращает массив со всеми данными.
Разберем по шагам его работу:
Запрос = Новый Запрос;
// Менеджер здесь создавать НЕ обязательно, если не планируете использовать ВТ в других запросах
Запрос.Текст =
"ВЫБРАТЬ 1 КАК Число ПОМЕСТИТЬ ВТ_Раз;
|ВЫБРАТЬ 2 КАК Число ПОМЕСТИТЬ ВТ_Два;
|ВЫБРАТЬ Число ИЗ ВТ_Раз";
РезультатыПакета = Запрос.ВыполнитьПакетСПромежуточнымиДанными();
// РезультатыПакета[0] содержит данные таблицы ВТ_Раз
// РезультатыПакета[1] содержит данные таблицы ВТ_Два
// РезультатыПакета[2] содержит результат финальной выборки
ТЗ_Первая = РезультатыПакета[0].Выгрузить();
Важное ограничение: этот метод выгружает абсолютно все таблицы пакета в оперативную память. Если в вашем пакете много тяжелых временных таблиц, это может привести к избыточной нагрузке на сервер.
Проанализируем ситуацию с производительностью. Чтобы работа с временными таблицами в коде была эффективной, придерживайтесь следующих правил:
ИНДЕКСИРОВАТЬ ПО. Без индексов соединение с ВТ на больших объемах данных будет крайне медленным.ВЫРАЗИТЬ() при помещении данных в ВТ, особенно для полей составного типа. Это ускорит создание индексов и упростит структуру таблицы в СУБД.МенеджерВременныхТаблиц можно передавать как параметр в другие процедуры и функции на сервере. Это гораздо эффективнее, чем передавать большие ТаблицаЗначений, так как данные остаются в базе данных и не сериализуются.ГДЕ В (&Список). Если список содержит десятки тысяч элементов, поместите их сначала в ТаблицаЗначений, затем передайте в запрос и поместите во временную таблицу.Таким образом, выбор метода зависит от вашей задачи: для отладки и быстрого получения всех данных используйте ВыполнитьПакетСПромежуточнымиДанными(), а для сложной многошаговой логики с сохранением ресурсов — МенеджерВременныхТаблиц.