Перенос информационной базы 1С из файлового режима работы в клиент-серверный вариант (на СУБД MS SQL Server) — это стандартная процедура при росте компании и увеличении количества пользователей. Однако в процессе загрузки файла резервной копии .dt системные администраторы часто сталкиваются с неприятным сбоем. Платформа прерывает операцию загрузки и выдает ошибку: «Попытка вставки неуникального значения в уникальный индекс».
В этой статье мы подробно разберем, почему возникает эта проблема, как расшифровать технический лог ошибки СУБД и какими способами можно быстро вернуть базу в рабочее состояние.
Для начала проанализируем природу поведения различных систем управления базами данных (СУБД). Собственный файловый движок 1С (файл 1Cv8.1CD) устроен менее строго, чем промышленные реляционные СУБД вроде MS SQL Server, PostgreSQL или Oracle. В результате аварийных завершений работы компьютера (например, отключение электричества), сбоев локальной сети или некорректных транзакций в таблицах файловой базы могут появиться логические дубликаты записей.
Файловая СУБД «молча» мирится с наличием таких дублирующихся строк, продолжая функционировать без видимых сбоев. Но как только мы выгружаем данные в .dt и пытаемся развернуть их на MS SQL, ситуация кардинально меняется:
CREATE UNIQUE INDEX для создания уникальных индексов, обеспечивающих быстродействие и ссылочную целостность.Таким образом, MS SQL Server выступает строгим цензором, который физически не позволяет импортировать «грязные» данные.
Рассмотрим детально текст типичной ошибки:
The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name 'dbo._AccumRgT22706' and the index name '_AccumRg22706_ByDims'.
Из этого сообщения мы можем извлечь массу полезной информации:
dbo._AccumRgT22706. Префикс _AccumRg указывает на то, что это регистр накопления. Символ «T» сразу после префикса однозначно говорит о том, что сбой произошел в таблице итогов этого регистра (а не в основной таблице движений)._AccumRg22706_ByDims. Это уникальный индекс, построенный по измерениям регистра (Dimensions).4018-02-01 00:00:00.Важное примечание о смещении дат: Дата 4018 год не должна вас пугать. Платформа 1С при работе с MS SQL по умолчанию использует механизм смещения дат на 2000 лет вперед. Это необходимо для корректного хранения пустых дат (01.01.0001), так как тип данных DATETIME в старых версиях SQL Server не поддерживает даты ранее 1753 года. Вычитаем из 4018 года смещение в 2000 лет и получаем реальную дату документа в нашей базе — 1 февраля 2018 года.
---
Поскольку виновником нашей ошибки является таблица с буквой «T» (таблица итогов _AccumRgT22706), мы можем решить проблему элегантно и без детального поиска поврежденных документов. Итоги в 1С — это вторичные, расчетные данные. Мы можем полностью удалить их, перенести базу в SQL в «облегченном» виде, а затем рассчитать заново.
Разберем этот алгоритм по шагам:
_AccumRgT. Таблицы становятся абсолютно пустыми, а значит, в них физически исчезают любые дубликаты..dt через Конфигуратор..dt. Загрузка гарантированно пройдет без ошибок уникальности по таблицам итогов.---
Если сбой происходит не в итогах, а в основной таблице движений регистра (таблица без символа «T», например, _AccumRg22706), предыдущий способ не поможет. Нам потребуется найти конкретный регистр в конфигурации и исправить неверные записи.
Проанализируем процесс поиска без использования сторонних утилит:
Для начала нам нужно сопоставить физическое имя таблицы СУБД _AccumRg22706 с логическим именем регистра в конфигураторе 1С. Для этого откроем Конфигуратор файловой базы, зайдем в меню «Сервис» — «Табло» (или откроем внешнюю обработку «Консоль кода») и выполним команду:
СтруктураБД = ПолучитьСтруктуруХраненияБазыДанных();
Для Каждого Таблица Из СтруктураБД Цикл
Если Таблица.ИмяТаблицыХранения = "_AccumRg22706" Тогда
Сообщить("Логическое имя регистра: " + Таблица.ИмяТаблицы);
КонецЕсли;
КонецЦикла;
Платформа выдаст человекочитаемое имя объекта метаданных, например: РегистрНакопления.ВыручкаИСебестоимостьПродаж.
Теперь мы можем написать простой запрос в режиме «Предприятие» (используя стандартную «Консоль запросов»), чтобы локализовать дублирующиеся записи. Запрос должен группировать записи по периоду и абсолютно всем измерениям регистра:
ВЫБРАТЬ
Регистр.Период КАК Период,
Регистр.АналитикаУчетаНоменклатуры КАК АналитикаУчетаНоменклатуры,
Регистр.ЗаказКлиента КАК ЗаказКлиента,
СУММА(1) КАК КоличествоДублей
ИЗ
РегистрНакопления.ВыручкаИСебестоимостьПродаж КАК Регистр
СГРУППИРОВАТЬ ПО
Регистр.Период,
Регистр.АналитикаУчетаНоменклатуры,
Регистр.ЗаказКлиента
ИМЕЮЩИЕ
СУММА(1) > 1
Обратите внимание: в секцию СГРУППИРОВАТЬ ПО необходимо включить все измерения вашего конкретного регистра.
Запрос вернет строки с количеством дублей больше единицы. Зная период (в нашем случае — февраль 2018 года) и конкретные измерения (номенклатуру, заказы), мы легко найдем документы-регистраторы, сделавшие эти движения.
После нахождения проблемных документов выполните следующие действия в файловой базе:
.dt и загрузки на сервер SQL.---
Иногда обычное перепроведение документов не помогает, так как поврежден сам индекс или структура файла 1CD на физическом уровне. В этом случае перед выгрузкой в SQL необходимо провести комплексное обслуживание файловой базы.
Выполним процедуру лечения по шагам:
C:\Program Files\1cv8\8.3.XX.XXXX\bin\) и запустите утилиту проверки физической целостности chdbfl.exe.---
Если база данных имеет огромный объем и стандартные процедуры исправления в файловом режиме занимают слишком много времени, администраторы используют обходной путь непосредственно на стороне SQL Server. Этот способ требует понимания работы СУБД:
.dt. Загрузка завершается успешно, так как SQL Server не пытается принудительно создать уникальный индекс при импорте.DELETE FROM dbo._AccumRgT22706 ...) находят и физически удаляют одну из дублирующихся строк.Важно: Этот метод является экстремальным и может нарушить логическую целостность данных с точки зрения платформы 1С. Рекомендуется использовать первые три метода как наиболее безопасные и документированные производителем.
Используя приведенные инструкции, мы можем быстро локализовать сбойную таблицу, очистить итоги или исправить дубликаты записей в документах, обеспечив плавный и беспроблемный переход на производительную серверную СУБД.