При миграции информационной базы 1С из файлового режима (файла .1CD) в клиент-серверный вариант под управлением Microsoft SQL Server через выгрузку и загрузку файла .dt часто возникает критическая ошибка. Процесс загрузки аварийно прерывается сообщением: «Попытка вставки неуникального значения в уникальный индекс: Microsoft SQL Server Native Client: Выполнение инструкции CREATE UNIQUE INDEX прервано, поскольку обнаружен повторяющийся ключ для объекта с именем "dbo._InfoRgXXXX" и индекса с именем "_InfoRgXXXX_ByDims"».
Разберем причины возникновения этой проблемы, научимся сопоставлять системное имя таблицы в СУБД с объектом метаданных конфигурации 1С и рассмотрим пошаговый алгоритм исправления дублирующихся записей.
Выясним, почему база, которая успешно работала в файловом режиме, отказывается разворачиваться на сервере СУБД:
.1CD могут приводить к нарушению логической целостности, из-за чего в регистр сведений записываются неуникальные комбинации измерений..dt не гарантирует целостность на уровне СУБД. При его загрузке сервер 1С создает структуру таблиц и выполняет команду создания уникального кластерного индекса по измерениям (_ByDims), которая завершается ошибкой при первом же дубле.Прежде чем исправлять данные, необходимо выяснить, какой именно регистр скрывается под системным именем таблицы (например, _InfoRg481). Префикс _InfoRg указывает на то, что проблемная таблица является регистром сведений (Information Register).
Откроем исходную файловую базу в режиме «1С:Предприятие» и выполним во внешней обработке программный код с использованием функции ПолучитьСтруктуруХраненияБазыДанных:
ТаблицаХранения = ПолучитьСтруктуруХраненияБазыДанных();
СтрокаПоиска = ТаблицаХранения.Найти("_InfoRg481", "ИмяТаблицыХранения");
Если СтрокаПоиска <> Неопределено Тогда
Сообщить("Имя объекта метаданных: " + СтрокаПоиска.ИмяТаблицы);
Сообщить("Метаданные: " + СтрокаПоиска.Метаданные);
Иначе
Сообщить("Таблица с указанным именем не найдена!");
КонецЕсли;
В результате работы кода мы получим реальное имя регистра сведений в конфигураторе (например, РегистрСведений.ЦеныНоменклатуры или РегистрСведений.СоответствиеОбъектовДляОбмена).
После выяснения имени регистра найдем дублирующиеся строки непосредственно в файловой базе. Для этого напишем запрос, сгруппированный по всем ключевым полям регистра (для периодических регистров добавляется поле Период, для подчиненных регистратору — Регистратор и НомерСтроки):
ВЫБРАТЬ
Т.Номенклатура КАК Номенклатура,
Т.ВидЦены КАК ВидЦены,
Т.Период КАК Период,
КОЛИЧЕСТВО(1) КАК КоличествоДублей
ИЗ
РегистрСведений.ЦеныНоменклатуры КАК Т
СГРУППИРОВАТЬ ПО
Т.Номенклатура,
Т.ВидЦены,
Т.Период
ИМЕЮЩИЕ
КОЛИЧЕСТВО(1) > 1
Этот запрос наглядно покажет, какие именно комбинации ключевых полей задвоены в базе данных.
Рассмотрим основные способы восстановления корректной структуры данных в исходной файловой базе перед повторной выгрузкой в .dt:
chdbfl.exe: Запустим утилиту физической проверки целостности файла базы данных (находится в каталоге bin установленной платформы 1С), выберем файл 1Cv8.1CD и установим флаг «Исправлять обнаруженные ошибки».- Реиндексация таблиц информационной базы;
- Проверка логической целостности информационной базы;
- Реструктуризация таблиц информационной базы.
Реструктуризация пересоздаст таблицы и индексы в файловой базе, что во многих случаях автоматически удалит некорректные связи или исправит индексные файлы.
СокрЛП к строковым полям и перезаписать набор данных.Число, применить конфигурацию базы данных (что заставит платформу выполнить реструктуризацию и перестроить индекс _ByDims), затем удалить добавленное измерение и снова сохранить конфигурацию.Если исправить файл .1CD не удается, перенесем данные в MS SQL без создания выгрузки через файл .dt:
.cf) и перенесем всю информацию с помощью типовой универсальной обработки в формате XML. При этом сбойный регистр сведений можно временно исключить из выгрузки и перенести отдельно после ручной очистки.После устранения неуникальных записей сформируем новую выгрузку в файл .dt и выполним повторную загрузку в базу MS SQL Server. Индекс _ByDims будет создан успешно.