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