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