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