К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как удалить временную таблицу в 1С

Как удалить временную таблицу в 1С: метод Уничтожить, работа с менеджером временных таблиц, очистка запроса, типичные ошибки и примеры кода на встроенном языке.

Временные таблицы в 1С создаются запросами с конструкцией ПОМЕСТИТЬ и хранятся в менеджере временных таблиц до конца его жизни. Если таблица больше не нужна, её следует удалить явно: это освобождает память сервера и предотвращает конфликты имён при повторном выполнении пакетного запроса.

Основной способ удаления — метод Уничтожить() объекта МенеджерВременныхТаблиц либо команда УНИЧТОЖИТЬ в тексте запроса. Оба подхода равнозначны по результату, но различаются по удобству в разных сценариях: динамическое удаление по имени удобнее делать методом, а очистку внутри пакетного запроса — командой языка запросов.

Ниже разобраны оба способа с примерами кода, ситуации, когда временная таблица удаляется автоматически, и типичные ошибки, из-за которых разработчики получают сообщение «Таблица уже существует» или теряют нужные данные.

Что такое временная таблица и где она хранится

Временная таблица — это материализованный результат запроса, помещённый во временное хранилище через инструкцию ПОМЕСТИТЬ ИмяТаблицы. Физически она размещается в памяти сервера 1С или во временной базе СУБД (например, в tempdb при работе с MS SQL Server) и существует только в рамках своего менеджера временных таблиц.

Менеджер временных таблиц (МенеджерВременныхТаблиц) — объект встроенного языка, который владеет всеми созданными таблицами. Пока существует менеджер и на него есть ссылка, таблицы доступны для чтения в последующих запросах. Как только менеджер уничтожается, все его таблицы удаляются вместе с ним.

Важно понимать: временные таблицы не попадают в журналы, не видны другим сеансам и не переживают завершение транзакции в некоторых конфигурациях соединений с СУБД. Это чисто рабочий инструмент для промежуточных вычислений внутри одного алгоритма.

Удаление командой УНИЧТОЖИТЬ в тексте запроса

Самый прямой способ — добавить в пакетный запрос команду УНИЧТОЖИТЬ с именем таблицы. Команда выполняется на стороне СУБД в составе пакета и не возвращает результат.

Запрос = Новый Запрос;

Запрос.МенеджерВременныхТаблиц = МенеджерВТ;

Запрос.Текст =

"ВЫБРАТЬ

| Товары.Номенклатура,

| Товары.Количество

|ПОМЕСТИТЬ ВТ_Товары

|ИЗ

| Документ.РеализацияТоваровУслуг.Товары КАК Товары

|ГДЕ

| Товары.Ссылка = &Ссылка

|;

|//////////////////////

|ВЫБРАТЬ

| ВТ_Товары.Номенклатура

|ИЗ

| ВТ_Товары КАК ВТ_Товары

|;

|//////////////////////

|УНИЧТОЖИТЬ ВТ_Товары";

Результат = Запрос.Выполнить();

В пакетном запросе команды разделяются точкой с запятой. УНИЧТОЖИТЬ ставят после последнего обращения к таблице. Если в пакете несколько временных таблиц, удалять их можно одной командой на каждую таблицу — перечисление через запятую в одной команде не поддерживается.

Обратите внимание: метод Выполнить() возвращает результат последнего выборочного оператора пакета, поэтому УНИЧТОЖИТЬ обычно ставят в самый конец либо используют ВыполнитьПакет(), когда нужны результаты нескольких выборок.

Удаление методом Уничтожить() менеджера временных таблиц

Когда имя таблицы хранится в переменной или удаление должно происходить по условию в коде, удобнее метод Уничтожить():

МенеджерВТ = Новый МенеджерВременныхТаблиц;

// ... запросы, создающие и использующие таблицы ...

МенеджерВТ.Уничтожить("ВТ_Товары");

Метод принимает строковое имя таблицы без префиксов. Если таблицы с таким именем в менеджере нет, будет вызвана ошибка выполнения, поэтому перед удалением стоит убедиться, что таблица существует, — особенно в коде, где создание таблицы происходит по условию.

Проверить наличие таблицы можно попыткой получить её через индексированное свойство менеджера или обернув удаление в Попытка ... Исключение ... КонецПопытки, если логика допускает отсутствие таблицы.

bsl
МенеджерВТ = Новый МенеджерВременныхТаблиц;
// ... работа с запросами ...
Если НужнаОчистка Тогда
    МенеджерВТ.Уничтожить("ВТ_Товары");
КонецЕсли;

Удаление всех таблиц через уничтожение менеджера

Если после блока вычислений временные таблицы больше не нужны совсем, отдельно удалять каждую не требуется. Достаточно обнулить ссылку на менеджер:

МенеджерВТ = Неопределено;

После этого сборщик мусора платформы освободит объект, а вместе с ним — все временные таблицы на стороне СУБД. Это самый чистый способ завершить работу, когда менеджер создавался локально внутри процедуры и никуда не передавался дальше.

Тонкость возникает, когда менеджер передаётся между процедурами или хранится в реквизите формы. Пока существует хотя бы одна живая ссылка на объект, таблицы продолжают занимать память. В долгоживущих формах и фоновых заданиях с большими выборками это может приводить к заметному потреблению памяти на сервере.

Когда временные таблицы удаляются автоматически

Явное удаление не всегда обязательно. Платформа сама очищает временные таблицы в следующих случаях:

  • завершилась процедура или функция, в которой менеджер был создан как локальная переменная, и других ссылок на него нет;
  • запрос выполнялся без назначенного менеджера временных таблиц — тогда платформа создаёт временный менеджер на время выполнения и уничтожает его сразу после;
  • завершился сеанс или фоновое задание — все временные объекты на стороне СУБД удаляются.

Из этого следует практический вывод: если запрос с ПОМЕСТИТЬ выполняется один раз и результат сразу читается, а менеджер не назначался явно, беспокоиться об удалении не нужно. Явная очистка требуется, когда один менеджер используется для серии запросов в цикле или между несколькими процедурами.

Маршрут решения

Как выбрать действие

Запрос выполняется один раз, менеджер не назначался явноНичего не делайте — платформа удалит таблицы автоматически
Один менеджер используется в цикле с созданием таблицУдаляйте таблицу командой УНИЧТОЖИТЬ или методом Уничтожить() на каждой итерации
Работа с менеджером полностью завершенаПрисвойте переменной Неопределено и убедитесь, что других ссылок нет
Имя таблицы формируется динамическиИспользуйте МенеджерВТ.Уничтожить(ИмяТаблицы) с предварительной проверкой существования

Типичные ошибки при удалении временных таблиц

Наиболее частая проблема — ошибка «Таблица уже существует» при повторном выполнении запроса с ПОМЕСТИТЬ в тот же менеджер. Она возникает в циклах, когда разработчик создаёт таблицу на каждой итерации, но не удаляет её в конце. Решение — либо удалять таблицу в конце итерации, либо переименовывать её, либо пересоздавать менеджер.

Обратная ошибка — попытка обратиться к таблице после её уничтожения. Если УНИЧТОЖИТЬ стоит в пакете раньше, чем запрос, читающий эту таблицу, выполнение прервётся с ошибкой. Порядок операторов в пакете имеет значение: сначала все чтения, потом удаление.

Третья типичная ситуация — удаление таблицы, которая используется в другом запросе, выполняемом позже в том же менеджере. Перед удалением полезно просмотреть весь код, работающий с данным менеджером, особенно если запросы разнесены по разным процедурам общего модуля.

Типичные ошибки
01
Создание таблицы в цикле без удаления — ошибка «Таблица уже существует» на второй итерации
02
УНИЧТОЖИТЬ раньше последнего чтения таблицы в пакете — ошибка выполнения запроса
03
Удаление таблицы, которая нужна другому запросу с тем же менеджером, — потеря данных в середине алгоритма
04
Вызов Уничтожить() для несуществующей таблицы без проверки — исключение времени выполнения
05
Хранение менеджера в реквизите формы без очистки — утечка памяти на сервере

Проверка результата и контроль памяти

Убедиться, что таблица удалена, можно простым тестом: после удаления выполнить запрос ВЫБРАТЬ * ИЗ ВТ_Товары в тот же менеджер. Если таблица удалена корректно, запрос завершится ошибкой «Таблица не найдена» — это и есть подтверждение в отладочных целях.

В продуктивном коде так проверять не нужно: достаточно дисциплины — каждая таблица, созданная в цикле или в переиспользуемом менеджере, удаляется сразу после последнего использования. При отладке больших пакетов удобно получать содержимое временной таблицы через консоль запросов, чтобы видеть, что именно остаётся в менеджере на каждом шаге.

Для длительных фоновых заданий с массивными выборками имеет смысл контролировать потребление памяти сервера через консоль кластера: если оно растёт пропорционально числу итераций, почти наверняка временные таблицы накапливаются без очистки.

Контрольные точки

Как проверить результат

Повторное выполнение запроса с ПОМЕСТИТЬ в тот же менеджер
Норма

Запрос выполняется без ошибки «Таблица уже существует»

Тревожный признак

Ошибка на втором выполнении — таблица не удалялась

Потребление памяти сервером в цикле обработки
Норма

Память стабильна между итерациями

Тревожный признак

Память растёт с каждой итерацией — таблицы копятся

Обращение к удалённой таблице в отладке
Норма

Ошибка «Таблица не найдена» — удаление сработало

Тревожный признак

Запрос возвращает данные — таблица ещё существует

Итог

Что важно запомнить

Временную таблицу удаляют командой УНИЧТОЖИТЬ в тексте запроса или методом МенеджерВТ.Уничтожить(Имя). Все таблицы исчезают вместе с менеджером, когда на него не осталось ссылок. В циклах и переиспользуемых менеджерах удаляйте таблицу сразу после последнего чтения — это защищает от ошибок «уже существует» и роста памяти.

Частые вопросы

Что будет, если не удалять временные таблицы вообще?

Ничего критичного при разовом выполнении: платформа удалит их вместе с менеджером по завершении процедуры. Проблемы начинаются в циклах (ошибка «Таблица уже существует») и в долгоживущих объектах, где накопленные таблицы занимают память сервера до завершения сеанса.

Можно ли удалить несколько таблиц одной командой УНИЧТОЖИТЬ?

Нет, язык запросов 1С не поддерживает перечисление имён в одной команде. Для каждой таблицы нужен отдельный оператор УНИЧТОЖИТЬ в пакете или отдельный вызов метода Уничтожить(). Альтернатива — уничтожить весь менеджер, если таблицы больше не нужны.

Как удалить временную таблицу, если её имя формируется динамически?

Используйте метод менеджера: МенеджерВТ.Уничтожить(ИмяТаблицы), где ИмяТаблицы — строковая переменная. В тексте запроса динамическое имя потребует подстановки через СтрШаблон или конкатенацию, что менее безопасно и хуже читается.

Удаляются ли временные таблицы при откате транзакции?

Нет. Команды ПОМЕСТИТЬ и УНИЧТОЖИТЬ не являются транзакционными операциями с данными информационной базы. Откат транзакции не восстановит удалённую временную таблицу и не удалит созданную — ими управляет только менеджер временных таблиц.

Чем УНИЧТОЖИТЬ в запросе отличается от метода Уничтожить()?

По результату — ничем: оба удаляют таблицу из менеджера. Команда в тексте запроса удобна внутри пакетных запросов, где вся логика собрана в одном тексте. Метод удобнее, когда решение об удалении принимается в коде по условию или имя таблицы хранится в переменной.