Как удалить дубликаты строк в таблице SQL и исправить ошибку создания уникального индекса в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При загрузке данных через распределенные информационные базы (РИБ), импорте файлов выгрузки .dt или реструктуризации базы данных на стороне СУБД MS SQL Server может возникать ошибка создания уникального индекса. Чаще всего проблема проявляется в таблицах с префиксом _InfoRgSL. Выясним причину такого поведения, разберем SQL-запрос для физического удаления дубликатов с сохранением одной уникальной строки, а также рассмотрим правильные способы устранения первопричины средствами платформы 1С.

Анализ проблемы: назначение таблицы _InfoRgSL и природа дублей

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

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

  1. Нарушение уникальности в основной таблице регистра (_InfoRg): в исходной базе (особенно файловой) из-за сбоев могли появиться записи с одинаковым периодом и измерениями. При переносе в клиент-серверный вариант платформа рассчитывает срез последних и пытается вставить дубли в служебную таблицу.
  2. Различие параметров сортировки (Collation): если в измерениях есть строковые данные, нечувствительность к регистру в SQL Server (например, Cyrillic_General_CI_AS) объединяет строки разного регистра, которые в исходной базе считались уникальными.
  3. Коллизии многопоточной загрузки: параллельные потоки при загрузке .dt могут одновременно инициировать пересчет итогов.

Решение 1: Удаление дубликатов в SQL с помощью CTE и оконной функции

Если необходимо экстренно завершить загрузку или операцию в СУБД, обычный запрос с DELETE WHERE ... IN (GROUP BY) приведет к полному удалению всей группы (включая оригинал). Чтобы удалить исключительно копии и оставить ровно одну запись из каждой группы дублей, используем обобщенное табличное выражение (CTE) и оконную функцию ROW_NUMBER().

Разберем по шагам логику работы скрипта:

  1. Оконная функция ROW_NUMBER() OVER (PARTITION BY ... ORDER BY ...) нумерует строки внутри каждой группы одинаковых измерений. Первая строка получает номер rn = 1, вторая — rn = 2 и так далее.
  2. Конструкция DELETE FROM DeleteDouble WHERE rn > 1 удаляет только те строки, чей порядковый номер в группе больше единицы.

Посмотрим на готовый пример SQL-запроса:


WITH DeleteDouble AS (
    SELECT 
        [_Fld21123RRef],
        [_Fld21124RRef],
        [_Fld21125RRef],
        ROW_NUMBER() OVER (
            PARTITION BY [_Fld21123RRef], [_Fld21124RRef], [_Fld21125RRef] 
            ORDER BY [_Fld21123RRef], [_Fld21124RRef], [_Fld21125RRef]
        ) AS rn
    FROM [dbo].[_InfoRgSL21137]
)
DELETE FROM DeleteDouble
WHERE rn > 1;

Обратите внимание: прямое удаление из _InfoRgSL является временной мерой. Так как эта таблица формируется автоматически, при следующей записи набора или пересчете итогов платформа снова прочитает данные из основной таблицы _InfoRg и может повторно создать дубли.

Решение 2: Исправление данных в исходной базе 1С

Чтобы исключить повторение ошибки, разберем регламентные шаги по очистке данных в базе-источнике перед выгрузкой или обменом:

  1. Проверка файловой базы утилитой: если источник работает в файловом режиме, закроем все сеансы и запустим проверку физической целостности с помощью утилиты chdbfl.exe.
  2. Тестирование и исправление: в режиме Конфигуратора выполним операцию Администрирование > Тестирование и исправление информационной базы с установленными флагами:
    1. Реиндексация таблиц информационной базы;
    2. Проверка логической целостности (с действием «Очищать ссылки» / «Удалять записи»);
    3. Пересчет итогов.
  3. Программный поиск дублей в 1С: выполним запрос к проблемному регистру сведений с группировкой по измерениям и периоду с условием ИМЕЮЩИЕ КОЛИЧЕСТВО(*) > 1. Лишние записи удалим перезаписью пустого набора записей с установленным отбором по измерениям.

Решение 3: Отключение итогов и настройка параметров загрузки

Если ошибка блокирует реструктуризацию в базе-приемнике, применим дополнительные системные приемы:

  1. Временное отключение среза последних: в дереве метаданных у проблемного регистра сведений снимем признак использования итогов срез последних. Применим изменения в базе данных (при этом таблица _InfoRgSL удалится), загрузим обновления, после чего снова включим итоги и выполним стандартный пересчет.
  2. Однопоточная загрузка выгрузки: если сбой возникает при разворачивании файла выгрузки, выполним восстановление через командную строку конфигуратора с ограничением числа параллельных потоков: 1cv8.exe DESIGNER /RestoreIB "C:\base_dump.dt" -JobsCount 1
  3. Исключение регистра из обмена: если регистр (например, история цен поставщиков) не требуется в узле-приемнике, снимем авторегистрацию изменений для этого регистра в плане обмена или очистим зарегистрированные коллизионные записи.
← На главную