Как быстро удалить все записи в справочнике 1С 7.7 (SQL)?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При работе с базами данных 1С:Предприятие 7.7 на платформе SQL часто возникает необходимость очистки справочников от большого объема данных. Стандартные методы встроенного языка, такие как перебор элементов и установка пометки удаления, работают крайне медленно из-за механизмов объектной обработки и контроля транзакций на каждый элемент. В этой статье мы подробно разберем, как ускорить этот процесс, используя прямые SQL-запросы, проанализируем риски использования команды TRUNCATE и рассмотрим наиболее безопасные "гибридные" методы.

Проблема стандартного удаления

Почему стандартный код работает долго? Когда мы используем конструкцию:


Спр = СоздатьОбъект("Справочник.Номенклатура");
Спр.ВыбратьЭлементы();
Пока Спр.ПолучитьЭлемент() = 1 Цикл
    Спр.Удалить(1); // Или УстановитьПометкуУдаления(1)
КонецЦикла;

Платформа 1С выполняет множество действий для каждой записи: считывает объект, блокирует его, проверяет права, регистрирует изменения в таблицах обмена (для УРБД), обновляет индексы и пишет в журнал транзакций. Если записей десятки или сотни тысяч, это может занять часы. Давайте рассмотрим альтернативные варианты, которые позволяют решить задачу за секунды или минуты.

Вариант 1: Радикальная очистка через TRUNCATE TABLE

В ходе обсуждения проблемы участники предложили использовать команду SQL TRUNCATE TABLE. Это самый быстрый способ очистки таблицы. Он работает практически мгновенно, так как не логирует удаление каждой строки отдельно, а просто освобождает страницы данных.

Для выполнения этого действия необходимо знать физическое имя таблицы справочника в базе данных SQL (обычно это имена вида SC..., например SC552). Найти соответствие можно в файле словаря данных 1Cv7.DD или используя специальные утилиты.

Запрос выглядит следующим образом:

TRUNCATE TABLE SC552

Преимущества:

  1. Скорость выполнения — доли секунды даже для миллионов записей.
  2. Не раздувает лог транзакций SQL (LDF-файл).

Серьезные недостатки и риски:

Несмотря на то, что этот метод сработал у автора вопроса, мы обязаны предупредить о скрытых проблемах, которые не всегда очевидны сразу:

  1. Нарушение ссылочной целостности. Команда TRUNCATE удаляет записи физически без проверки ссылок. Если на удаленные элементы ссылаются документы или другие справочники, в базе появятся "битые ссылки" (знаменитые <Объект не найден...>).
  2. Мусор в периодических реквизитах (1SCONST). Это критически важный момент для 1С 7.7. Значения периодических реквизитов хранятся в отдельной таблице 1SCONST. При использовании TRUNCATE основной таблицы справочника, записи в 1SCONST остаются. Это приводит к накоплению "мертвых" данных, которые привязаны к несуществующим ID.
  3. Проблемы с УРБД. Если у вас распределенная база данных, команда TRUNCATE не регистрирует изменения в системной таблице _1SUPDTS. Периферийные базы "не узнают", что данные были удалены, что приведет к рассинхронизации.

Вариант 2: SQL-запрос DELETE

Более классический подход в SQL — использование оператора DELETE. Посмотрим на отличия:

DELETE FROM SC552

В отличие от TRUNCATE, эта операция полностью протоколируется. Если таблица огромная, лог транзакций может вырасти до критических размеров. Кроме того, DELETE также не очищает таблицу 1SCONST и не регистрирует изменения для УРБД автоматически.

Вариант 3: Гибридный метод (Рекомендуемый)

Давайте проанализируем наиболее сбалансированное решение, которое сочетает скорость SQL и безопасность штатных механизмов 1С. Суть метода заключается в массовой установке пометки удаления через прямой запрос SQL, с последующим штатным удалением.

Шаг 1: Массовая пометка на удаление через SQL

Вместо физического удаления, мы используем команду UPDATE, чтобы установить флаг пометки удаления (поле ISMARK) в значение 1. Это происходит очень быстро.

Пример запроса:


UPDATE SC552 
SET ISMARK = 1 
WHERE ISMARK = 0 -- Помечаем только те, что еще не помечены

Если необходимо установить пометку удаления не для всех, а по условию, можно добавить фильтрацию:


UPDATE SC552 
SET ISMARK = 1 
FROM SC552 
WHERE SC552.DESCR LIKE '%Удалить%'

Шаг 2: Штатное удаление помеченных объектов

После выполнения SQL-запроса мы заходим в 1С в монопольном режиме и запускаем стандартную обработку "Удаление помеченных объектов".

Почему это правильно:

  1. Контроль ссылочности. Система проверит, используются ли удаляемые элементы в документах. Если используются — удаление будет заблокировано, что спасет базу от ошибок.
  2. Очистка 1SCONST. Штатный механизм удаления корректно подчистит историю значений периодических реквизитов.
  3. Корректная работа УРБД. При удалении объектов через штатную процедуру, факт удаления (физического исчезновения записи) будет зарегистрирован для обмена.

Особенности работы с УРБД (Распределенные базы)

Если ваша база данных участвует в обмене, обратите особое внимание на тот факт, что прямые запросы (SQL) идут в обход механизмов регистрации изменений 1С. Таблица регистрации изменений называется _1SUPDTS.

Если вы "грохнули" записи через TRUNCATE или DELETE в центральной базе:

В случае использования УРБД, гибридный метод (SQL Update IsMark + Штатное удаление) является единственно верным безопасным путем, так как он задействует стандартные механизмы удаления, которые "знают" об обмене.

Действия после прямого удаления

Если вы все же решили использовать DELETE или массовую вставку/удаление, давайте разберем, какие регламентные операции на SQL Server необходимо выполнить для поддержания здоровья базы:

  1. Shrink Database (Сжатие). После массового удаления место на диске не освобождается автоматически, файлы данных остаются "раздутыми". Операция Shrink позволяет вернуть место операционной системе.
  2. Update Statistics (Обновление статистики). SQL Optimizer строит планы запросов на основе статистики распределения данных. После резкого изменения количества строк статистика устаревает, и 1С может начать "тормозить" на простых операциях.
  3. Rebuild/Reorganize Indexes (Перестройка индексов). Операция DELETE сильно фрагментирует индексы. Их необходимо перестроить. TRUNCATE в этом плане лучше, так как он сбрасывает индексы, но, как мы выяснили, он опасен по другим причинам.

Использование 1С++ для автоматизации

Чтобы не искать имена таблиц (типа SC552) вручную в файле DD, можно использовать внешнюю компоненту 1С++ и класс MetaDataWork. Это позволяет писать универсальный код.

Пример логики кода на 1С с использованием прямых запросов:


ТекстЗапроса = "
|UPDATE " + MetaDataWork.ПолучитьИмяТаблицыСправочника("Номенклатура") + "
|SET ISMARK = 1
|WHERE ISMARK = 0
|";

Такой подход позволяет автоматизировать процесс пометки удаления, сохраняя при этом гибкость кода и независимость от конкретной структуры базы данных (которая может меняться после обновлений конфигурации).

Выводы

Подведем итог. Для быстрого удаления записей:

  1. Если справочник временный, не имеет ссылок на себя, не имеет периодических реквизитов и база не распределенная — можно рискнуть и использовать TRUNCATE.
  2. Во всех остальных случаях (особенно в рабочих, "боевых" базах) — используйте комбинацию: Прямой запрос SQL для установки пометки удаления + Штатное удаление помеченных объектов. Это сэкономит часы ручной пометки и гарантирует целостность базы.
← На главную