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