Как очистить таблицу регистрации изменений 1SUPDTS в 1С 7.7 через SQL?

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

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

Поймем назначение и структуру таблицы 1SUPDTS

Прежде чем приступать к удалению, проанализируем, как устроена эта системная таблица в среде MS SQL Server. Она содержит минимальный набор полей, необходимых для идентификации изменений:

  1. DBSIGN — Идентификатор базы-получателя. Это уникальная метка (обычно трехсимвольный код), которая указывает, для какой дочерней базы предназначена эта запись.
  2. TYPEID — Идентификатор типа метаданных. Каждому виду объекта в 1С (например, справочнику "Контрагенты" или документу "РасходнаяНакладная") соответствует свой уникальный числовой ID.
  3. OBJID — Внутренний 36-ричный идентификатор конкретного объекта базы данных.
  4. DELETED — Флаг удаления объекта (если объект был удален, в этом поле фиксируется соответствующая метка).

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

Решение 1: Использование внешней компоненты 1С++ (ODBCRecordset)

Наиболее технологичным и быстрым способом в среде 7.7 является использование компоненты 1С++. Она позволяет выполнять прямые SQL-запросы к базе данных MS SQL без необходимости создания отдельных соединений через Windows-драйверы, используя уже установленное соединение текущей сессии.

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


// Создаем объект для работы с SQL
ЗапросSQL = СоздатьОбъект("ODBCRecordset");

// Формируем текст запроса на удаление
// Заменяем 'AAA' на код вашей периферийной базы
// TYPEID можно узнать через Метаданные.Документ("НужныйДокумент").Идентификатор
ТекстЗапроса = "
| DELETE FROM 1SUPDTS 
| WHERE DBSIGN = 'AAA' 
| AND TYPEID = 125
|";

// Выполняем запрос
Если ЗапросSQL.Выполнить(ТекстЗапроса) = 0 Тогда
    Сообщить("Ошибка выполнения запроса: " + ЗапросSQL.ПолучитьОписаниеОшибки());
Иначе
    Сообщить("Регистрация изменений успешно очищена.");
КонецЕсли;

Преимущество этого метода в том, что он работает в контексте текущей транзакции и позволяет использовать мощный синтаксис T-SQL.

Решение 2: Прямое подключение через ADO (ActiveX Data Objects)

Если в системе по каким-то причинам не установлена компонента 1С++, мы можем воспользоваться универсальным механизмом ADO. Этот метод требует явного указания строки подключения к серверу SQL.

Рассмотрим пример кода для подключения и очистки таблицы:


// Создаем объекты ADO
Connection = СоздатьОбъект("ADODB.Connection");
Command = СоздатьОбъект("ADODB.Command");

// Строка подключения (настройте под свои параметры сервера)
ConnectionString = "Provider=SQLOLEDB.1;Data Source=SERVER_NAME;Initial Catalog=BASE_NAME;User ID=sa;Password=your_password;";

Попытка
    Connection.Open(ConnectionString);
    Command.ActiveConnection = Connection;
    
    // SQL запрос на удаление записей старше определенной даты через JOIN с журналом (пример)
    // В самой 1SUPDTS даты нет, поэтому связываемся с 1SJOURN по OBJID
    Command.CommandText = "
    | DELETE dts 
    | FROM 1SUPDTS as dts
    | INNER JOIN 1SJOURN as journ ON dts.OBJID = journ.IDDOC
    | WHERE journ.DATE_TIME_IDDOC < '20230101'
    | AND dts.DBSIGN = 'BBB'";
    
    Command.Execute();
    Connection.Close();
    Сообщить("Очистка успешно завершена.");
Исключение
    Сообщить("Ошибка подключения или выполнения запроса: " + ОписаниеОшибки());
КонецПопытки;

Стратегии фильтрации: что именно удалять?

Проанализируем различные ситуации, когда требуется выборочная очистка 1SUPDTS, так как полная очистка (TRUNCATE TABLE) требуется крайне редко:

Критически важные риски и меры предосторожности

Работа с системными таблицами 1С напрямую через SQL — это "хирургическое" вмешательство. Выясним, какие опасности подстерегают программиста:

  1. Нарушение ссылочной целостности: Это самая главная опасность. Если вы удалите регистрацию изменения для нового элемента справочника (например, "НовыйКонтрагент"), но оставите регистрацию для нового документа, который ссылается на этого контрагента, то в дочерней базе при загрузке возникнет Битая Ссылка (Объект не найден).
  2. Блокировки (Deadlocks): Таблица 1SUPDTS — одна из самых нагруженных. При каждой записи любого объекта в 1С происходит INSERT в эту таблицу. Если вы запустите тяжелый DELETE на миллион строк в разгар рабочего дня, вы заблокируете работу всех пользователей. Рекомендация: проводите такие операции только в монопольном режиме или в часы минимальной активности.
  3. Транзакционные логи: Массовое удаление строк генерирует большой объем записей в логе транзакций SQL (.ldf файл). Убедитесь, что на диске достаточно места, или выполняйте удаление порциями (через DELETE TOP (1000) в цикле).

Резюме: Использование SQL для работы с 1SUPDTS оправдано только тогда, когда стандартный метод УдалитьРегистрациюИзменений() не справляется с объемом данных. В большинстве случаев связка 1С++ + ODBCRecordset является наиболее эффективным инструментом для решения этой задачи.

← На главную