При обслуживании и свертке высоконагруженных баз данных на платформе 1С:Предприятие 7.7 (SQL) штатные методы очистки регистров через перебор документов могут выполняться крайне долго. Когда требуется быстро удалить данные по определенным группам номенклатуры (например, закрытым направлениям или архивным позициям, содержащим десятки тысяч элементов), разработчики прибегают к прямым запросам с использованием внешней компоненты 1С++.
Разберем по шагам, как правильно подготовить список объектов, передать его во временную таблицу SQL, корректно составить инструкцию DELETE для таблиц движений и итогов, а также избежать критических ошибок при выполнении запроса.
Для фильтрации данных по иерархии справочника необходимо собрать список целевых элементов. Метод УложитьСписокОбъектов компоненты ODBCRecordSet позволяет передать список значений 1С напрямую во временную таблицу SQL (например, #СписокНоменклатуры), к которой затем можно обращаться через оператор IN или объединения JOIN.
Рассмотрим пример формирования списка и создания объекта прямого запроса:
Запрос = СоздатьОбъект("ODBCRecordSet");
// Передаем сформированный список групп/элементов во временную таблицу SQL
Запрос.УложитьСписокОбъектов(МойСписокНоменклатуры, "#СписокНоменклатуры", "Номенклатура");
Перед физическим удалением записей из базы данных настоятельно рекомендуется проверить количество и состав строк, попадающих под условие. Для этого выполним выборку с помощью инструкции SELECT.
Выясним разницу между методами выполнения запросов в 1С++:
ВыполнитьИнструкцию — возвращает полную таблицу значений (ТаблицаЗначений) или индексированную таблицу, что удобно для визуального просмотра строк.ВыполнитьСкалярный — возвращает единственное скалярное значение (или структуру при выборе нескольких колонок первой строки). Идеально подходит для подсчета количества строк через агрегатную функцию COUNT(*) или выполнения команд модификации данных (DELETE, UPDATE).Посмотрим на пример предварительного просмотра записей в таблице значений:
ТекстЗапросаСелект = "
|SELECT *
|FROM $Регистр.ПартииНаличие AS ПартииНаличие
|WHERE $ПартииНаличие.Номенклатура IN (SELECT val FROM #СписокНоменклатуры)
|";
ТЗ = Запрос.ВыполнитьИнструкцию(ТекстЗапросаСелект);
ТЗ.ВыбратьСтроку("Записи регистра, подлежащие удалению");
Если требуется быстро узнать только количество удаляемых записей, используем конструкцию со скалярным запросом:
ТекстКоличество = "
|SELECT COUNT(*)
|FROM $Регистр.ПартииНаличие AS ПартииНаличие
|WHERE $ПартииНаличие.Номенклатура IN (SELECT val FROM #СписокНоменклатуры)
|";
КоличествоЗаписей = Запрос.ВыполнитьСкалярный(ТекстКоличество);
Сообщить("Будет удалено записей: " + КоличествоЗаписей);
При выполнении команд удаления в Microsoft SQL Server часто возникает ошибка State 42000, native 156, message Неправильный синтаксис около ключевого слова 'AS'. В диалекте T-SQL при удалении нельзя указывать псевдоним таблицы напрямую через конструкцию DELETE FROM Таблица AS Псевдоним.
Проанализируем корректные варианты написания запроса:
DELETE, например: DELETE Псевдоним FROM Таблица AS Псевдоним WHERE ....Рассмотрим рабочий код очистки таблицы движений ($Регистр.ПартииНаличие) и таблицы периодических итогов ($РегистрИтоги.ПартииНаличие):
ТекстУдаления = "
|DELETE FROM $Регистр.ПартииНаличие
|WHERE $Регистр.ПартииНаличие.Номенклатура IN (SELECT val FROM #СписокНоменклатуры)
|
|DELETE FROM $РегистрИтоги.ПартииНаличие
|WHERE $РегистрИтоги.ПартииНаличие.Номенклатура IN (SELECT val FROM #СписокНоменклатуры)
|";
Запрос.ВыполнитьСкалярный(ТекстУдаления);
Сообщить("Удаление движений и итогов успешно завершено.");
При массовом удалении сотен тысяч строк в одной транзакции Microsoft SQL Server активно логирует каждую операцию, что приводит к ошибке: Журнал транзакций для базы данных заполнен (native 9002).
Разберем действия для устранения и предотвращения этой ошибки:
LOG), а также наличие свободного места на физическом диске.Simple Recovery Model) выполните операцию сжатия файла лога (DBCC SHRINKFILE).DELETE TOP (N) в цикле до полной очистки.Прямое вмешательство в таблицы базы данных в обход объектной модели платформы 1С 7.7 требует повышенной осторожности. Учитывайте следующие особенности архитектуры:
RA...) и итогов (RG...) не изменяет флаги проведенности и табличные части самих документов. При любой последующей перепроводке документов платформа заново запишет движения в регистр.