При загрузке данных через распределенные информационные базы (РИБ), импорте файлов выгрузки .dt или реструктуризации базы данных на стороне СУБД MS SQL Server может возникать ошибка создания уникального индекса. Чаще всего проблема проявляется в таблицах с префиксом _InfoRgSL. Выясним причину такого поведения, разберем SQL-запрос для физического удаления дубликатов с сохранением одной уникальной строки, а также рассмотрим правильные способы устранения первопричины средствами платформы 1С.
Таблицы СУБД с префиксом _InfoRgSL (например, _InfoRgSL21137) являются служебными физическими таблицами платформы 1С. В них сохраняются кэшированные агрегаты и итоги для виртуальной таблицы Срез последних периодических регистров сведений, если для регистра включено свойство хранения итогов.
Платформа требует наличия уникального индекса по комбинации измерений в этой таблице. Если при загрузке данных в таблице среза формируются две или более записи с одинаковыми значениями ключевых полей, СУБД прерывает процесс построения уникального индекса с ошибкой дублирования ключа. Проанализируем основные причины появления таких ситуаций:
_InfoRg): в исходной базе (особенно файловой) из-за сбоев могли появиться записи с одинаковым периодом и измерениями. При переносе в клиент-серверный вариант платформа рассчитывает срез последних и пытается вставить дубли в служебную таблицу.Cyrillic_General_CI_AS) объединяет строки разного регистра, которые в исходной базе считались уникальными..dt могут одновременно инициировать пересчет итогов.Если необходимо экстренно завершить загрузку или операцию в СУБД, обычный запрос с DELETE WHERE ... IN (GROUP BY) приведет к полному удалению всей группы (включая оригинал). Чтобы удалить исключительно копии и оставить ровно одну запись из каждой группы дублей, используем обобщенное табличное выражение (CTE) и оконную функцию ROW_NUMBER().
Разберем по шагам логику работы скрипта:
ROW_NUMBER() OVER (PARTITION BY ... ORDER BY ...) нумерует строки внутри каждой группы одинаковых измерений. Первая строка получает номер rn = 1, вторая — rn = 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 и может повторно создать дубли.
Чтобы исключить повторение ошибки, разберем регламентные шаги по очистке данных в базе-источнике перед выгрузкой или обменом:
chdbfl.exe.ИМЕЮЩИЕ КОЛИЧЕСТВО(*) > 1. Лишние записи удалим перезаписью пустого набора записей с установленным отбором по измерениям.Если ошибка блокирует реструктуризацию в базе-приемнике, применим дополнительные системные приемы:
_InfoRgSL удалится), загрузим обновления, после чего снова включим итоги и выполним стандартный пересчет.
1cv8.exe DESIGNER /RestoreIB "C:\base_dump.dt" -JobsCount 1