Работу с обработкой можно поделить на 3 части:
1) Выбор объектов для удаления и настройка отборов
2) Формирование текстов запросов
3) Выполнение запросов
Объекты и их настройки
Объекты
Удалить можно следующие объекты:
- Справочники (+ТЧ, Подчиненные с их ТЧ, Подчиненные подчиненных и тд)
- Документы (+Движения, Журналы, Последовательности, ТЧ)
- Регистры сведений (только основная таблица)
- Регистры накопления (только основная таблица)
- Регистры бухгалтерии (только основная таблица, +Субконто)
- Бизнес процессы (+ТЧ, Задачи с их ТЧ - не учитываются вложенные БП)
- Задачи (+ТЧ)
Регистры расчета пока что не включены в этот список, буду уже смотреть по количеству желающих.
То что указано в скобках тоже удаляется вместе с основным объектом.
Поясню ситуацию с вложенными БП при удалении основного: реализация подобного пока что мне кажется слишком трудоемкой, и возможно не нужной. Анализировать карту маршрута для выявления какой именно БП может быть вложенным - не предлагать, так как мой опыт говорит об использовании совсем не тривиальных схем с переопределением БП. Самый простой способ - это удалять БП с учетом порядка и правильного отбора.
Отборы
Для настройки отборов в таблице есть специальная колонка, проваливаемся туда и получаем полноценный редактор отборов СКД:
Отбор можно делать только по реквизитам (основным, стандартным, общим и тд), по ТЧ нельзя. Отбор можно делать по полям полей (через точку), количество уровней не ограничено. В отборе можно применять любые группировки условий (И, ИЛИ, НЕ).
Поддерживаются следующие виды сравнения:
- Равно
- Не равно
- Больше
- Больше или равно
- Меньше
- Меньше или равно
- Соответствует шаблону
- Не соответствует шаблону
- В списке
- Не в списке
Другие виды сравнения будут выдавать ошибку при формировании запросов. К сожалению я не нашел простого способа оставить только разрешенные виды, хитрый СКД все равно подставляет свое, поэтому тратить время на написание своего отборщика не стал.
Если кому то нужно сделать отборы "В группе", то для этого сделайте группу отборов "ИЛИ" и добавьте отборы вида Родитель.Родитель.Родитель и тд. Да, этот вариант будет не производительным как у 1С, да и я тут не стал особо заморачиваться с этим, но тем не менее для данной обработки в самый раз.
Составные типы
Отдельно стоит остановиться на составных типах. В обработке учтено практически все что с ними связано). Основная сложность это обработка обращений через точку, аля вида Регистратор.Дата. В данном случае к основной таблице будут соединятся все, которые только может содержать составной тип (собстно как и у 1С). Так же учтено что конечного реквизита может и не быть у некоторых таблиц и их в итоговом запросе не будет: как пример имеем отбор Регистратор.СкладОтправитель, и из 10 документов-регистраторов только 2 имеют конечный реквизит СкладОтправитель, вот именно эти 2 таблицы и будут присоединены к основной.
Можно делать отбор по значению НЕОПРЕДЕЛЕНО.
Сохранение и загрузка настроек
Все сделанные настройки можно сохранить для последующего повторного использования. Это может пригодиться для выполнения регламента подготовки базы для разработки или для удаления в нескольких базах.
Формирование запросов
Для того чтобы получить запросы нужно нажать на кнопку "Получить запросы БД". После этого по всем отмеченным объектам будут сформированы запросы на основании отборов. Сам текст будет размещен в соответствующей колонке. На данном этапе настройку подключения делать не нужно.
Текст запроса содержит в себе:
- Объявление некоторых переменных, одна из которых это YearOffset, так как на момент формирования оффсет еще не известен, то он закоменчен.
- Порции запросов на выполнение, разделенных строкой --GO. Чуть позже напишу зачем.
- Цикл выполнения порции запроса с учетом значения в поле "Размер порции"
По мимо основного объекта, в текст добавляются на удаление еще и зависимые (описаны выше), причем порядок именно такой, что основной объект будет удаляться в самом конце.
При построении отборов с применением даты, учитывается оффсет как равный 0, так и 2000. Пустые даты при этом соответственно подгоняются под него.
Соединения для элементов отборов формируются независимо. Как пример есть 2 элемента отбора Родитель.Родитель и Родитель.Родитель.Родитель, так вот в итоговом тексте запроса будет 2 соединения Родитель.Родитель. Да, одно соединение лишнее, но так было проще сделать. Будем надеется что великий скуль все заоптимизирует).
Если отборов нет, то будет TRUNCATE TABLE. Но так как с объектом удаляются еще и зависимые и они могут содержать в себе не только данные удаляемого, как пример регистр накопления, где может быть несколько регистраторов, то для них данная ситуация учитывается и будет не TRUNCATE зависимого, а удаление по типу объекта.
Сам текст запроса формируется с форматированием, комментами и тд. Так что не придется ломать глаза, разбирая месиво букв.
Если что не нравится в запросе, то можно его и отредактировать, провалившись в соответствующее поле.
Пример текста запроса:
--declare @YearOffset int = ?
declare @RowsDeleted int
--GO
--РегистрНакопления.Продажи
SET @RowsDeleted = 1
WHILE (@RowsDeleted > 0)
BEGIN
DELETE TOP (100000) AccumRg53
FROM
_AccumRg53 AS AccumRg53 with (tablockx)
INNER JOIN --Документ.РеализацияТоваровУслуг
_Document35 AS Document35 with (nolock)
ON
AccumRg53._RecorderRRef=Document35._IDRRef
AND AccumRg53._RecorderTRef=CAST(35 AS binary(4))
WHERE
(--Номер
Document35._Number = '111'
)
SET @RowsDeleted = @@ROWCOUNT
END
--GO
--Документ.РеализацияТоваровУслуг.Товары
SET @RowsDeleted = 1
WHILE (@RowsDeleted > 0)
BEGIN
DELETE TOP (100000) Document35_VT45
FROM
_Document35_VT45 AS Document35_VT45 with (tablockx)
INNER JOIN --Документ.РеализацияТоваровУслуг
_Document35 AS Document35 with (nolock)
ON
Document35_VT45._Document35_IDRRef=Document35._IDRRef
WHERE
(--Номер
Document35._Number = '111'
)
SET @RowsDeleted = @@ROWCOUNT
END
--GO
--Документ.РеализацияТоваровУслуг
SET @RowsDeleted = 1
WHILE (@RowsDeleted > 0)
BEGIN
DELETE TOP (100000) Document35
FROM
_Document35 AS Document35 with (tablockx)
WHERE
(--Номер
Document35._Number = '111'
)
SET @RowsDeleted = @@ROWCOUNT
END
--GO
Текст запроса можно, даже, выполнять не обработкой, а скопировать в менеджмент студио и выполнить там.
Посмотреть только отмеченные объекты для формирования/выполнения запросов можно по кнопке со стрелкой (рядом с кнопкой получения запросов). Это очень удобно когда их много и они разбросаны по разным коллекциям метаданных.
Выполнение запросов
Перед выполнением необходимо настроить подключение, для этого надо жамкнуть на гиперссылку рядом с кнопкой выполнения. Откроется окно:
Тут же есть кнопка проверки соединения.
Также перед выполнением можно поменять порядок удаления объектов. Находится он в последней колонке и задан только у коллекций. Но можно задать у конкретного объекта, в противном случае будет браться порядок коллекции.
При нажатии на кнопку выполнения производятся следующие действия:
- Установка соединения
- Построение запросов с учетом порядка
- Получение YearOffset за место закоменченного
- Разбитие текста запроса на порции по разделителю --GO, другими словами выполняется не весь запрос целиком, каждая порция отдельно, при этом первая порция объявления переменных присоединяется ко всем последующим
- Вывод состояния выполнения с прогресс баром
Все выполнение идет на клиенте и в любой момент можно прервать.
По окончанию выводится информация о длительности и количестве удаленных.
Для уменьшения таблиц итогов регистров и для их актуализации после чистки - выполнить пересчет итогов, реструктуризацию и тд.
Ну и шринкануть базу для получения эффекта)
PS
При проверки на порцию в 100000 объектов мне хватало 700-800мб журнала транзакций, но конечно же все зависит от таблицы.