Как исправить ошибку «Попытка вставки неуникального значения в уникальный индекс» при переносе базы 1С в MS SQL

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

Перенос информационной базы 1С из файлового режима работы в клиент-серверный вариант (на СУБД MS SQL Server) — это стандартная процедура при росте компании и увеличении количества пользователей. Однако в процессе загрузки файла резервной копии .dt системные администраторы часто сталкиваются с неприятным сбоем. Платформа прерывает операцию загрузки и выдает ошибку: «Попытка вставки неуникального значения в уникальный индекс».

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

Выясняем причину: почему файловая база работает, а MS SQL выдает ошибку?

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

Файловая СУБД «молча» мирится с наличием таких дублирующихся строк, продолжая функционировать без видимых сбоев. Но как только мы выгружаем данные в .dt и пытаемся развернуть их на MS SQL, ситуация кардинально меняется:

  1. Платформа 1С создает структуру таблиц на сервере MS SQL.
  2. Переносит физические данные из файла резервной копии.
  3. Пытается выполнить SQL-инструкцию CREATE UNIQUE INDEX для создания уникальных индексов, обеспечивающих быстродействие и ссылочную целостность.
  4. СУБД MS SQL обнаруживает в таблице две или более абсолютно одинаковые строки по ключевым полям и мгновенно прерывает транзакцию, возвращая ошибку с кодом 1505.

Таким образом, 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'.

Из этого сообщения мы можем извлечь массу полезной информации:

Важное примечание о смещении дат: Дата 4018 год не должна вас пугать. Платформа 1С при работе с MS SQL по умолчанию использует механизм смещения дат на 2000 лет вперед. Это необходимо для корректного хранения пустых дат (01.01.0001), так как тип данных DATETIME в старых версиях SQL Server не поддерживает даты ранее 1753 года. Вычитаем из 4018 года смещение в 2000 лет и получаем реальную дату документа в нашей базе — 1 февраля 2018 года.

---

Решение 1. Самый быстрый способ — «Трюк с итогами»

Поскольку виновником нашей ошибки является таблица с буквой «T» (таблица итогов _AccumRgT22706), мы можем решить проблему элегантно и без детального поиска поврежденных документов. Итоги в 1С — это вторичные, расчетные данные. Мы можем полностью удалить их, перенести базу в SQL в «облегченном» виде, а затем рассчитать заново.

Разберем этот алгоритм по шагам:

  1. Запустите исходную файловую базу в режиме «1С:Предприятие».
  2. Перейдите в меню управления итогами. В современных конфигурациях (например, УТ 11, ERP, КА) это можно сделать через раздел «Администрирование» — «Обслуживание» — «Регламентные операции» — «Управление итогами» (или воспользовавшись поиском через «Функции для технического специалиста»).
  3. Выберите все регистры накопления и выполните команду «Отключить использование итогов».
  4. При отключении итогов платформа физически очищает и удаляет все записи из таблиц с префиксом _AccumRgT. Таблицы становятся абсолютно пустыми, а значит, в них физически исчезают любые дубликаты.
  5. Выполните выгрузку информационной базы в файл .dt через Конфигуратор.
  6. В СУБД MS SQL создайте новую пустую базу данных, зарегистрируйте ее на сервере 1С и запустите загрузку полученного файла .dt. Загрузка гарантированно пройдет без ошибок уникальности по таблицам итогов.
  7. После успешной загрузки зайдите в базу на SQL в режиме «Предприятие», вернитесь в форму «Управление итогами», включите использование итогов обратно и запустите операцию «Полный пересчет итогов». Платформа сама последовательно пересчитает и запишет корректные, очищенные от дублей итоги на основе документов движения.

---

Решение 2. Локализация проблемного регистра и удаление дублей вручную

Если сбой происходит не в итогах, а в основной таблице движений регистра (таблица без символа «T», например, _AccumRg22706), предыдущий способ не поможет. Нам потребуется найти конкретный регистр в конфигурации и исправить неверные записи.

Проанализируем процесс поиска без использования сторонних утилит:

Для начала нам нужно сопоставить физическое имя таблицы СУБД _AccumRg22706 с логическим именем регистра в конфигураторе 1С. Для этого откроем Конфигуратор файловой базы, зайдем в меню «Сервис» — «Табло» (или откроем внешнюю обработку «Консоль кода») и выполним команду:


СтруктураБД = ПолучитьСтруктуруХраненияБазыДанных();
Для Каждого Таблица Из СтруктураБД Цикл
    Если Таблица.ИмяТаблицыХранения = "_AccumRg22706" Тогда
        Сообщить("Логическое имя регистра: " + Таблица.ИмяТаблицы);
    КонецЕсли;
КонецЦикла;

Платформа выдаст человекочитаемое имя объекта метаданных, например: РегистрНакопления.ВыручкаИСебестоимостьПродаж.

Теперь мы можем написать простой запрос в режиме «Предприятие» (используя стандартную «Консоль запросов»), чтобы локализовать дублирующиеся записи. Запрос должен группировать записи по периоду и абсолютно всем измерениям регистра:


ВЫБРАТЬ
    Регистр.Период КАК Период,
    Регистр.АналитикаУчетаНоменклатуры КАК АналитикаУчетаНоменклатуры,
    Регистр.ЗаказКлиента КАК ЗаказКлиента,
    СУММА(1) КАК КоличествоДублей
ИЗ
    РегистрНакопления.ВыручкаИСебестоимостьПродаж КАК Регистр
СГРУППИРОВАТЬ ПО
    Регистр.Период,
    Регистр.АналитикаУчетаНоменклатуры,
    Регистр.ЗаказКлиента
ИМЕЮЩИЕ
    СУММА(1) > 1

Обратите внимание: в секцию СГРУППИРОВАТЬ ПО необходимо включить все измерения вашего конкретного регистра.

Запрос вернет строки с количеством дублей больше единицы. Зная период (в нашем случае — февраль 2018 года) и конкретные измерения (номенклатуру, заказы), мы легко найдем документы-регистраторы, сделавшие эти движения.

После нахождения проблемных документов выполните следующие действия в файловой базе:

  1. Распроведите найденные документы.
  2. Убедитесь, что движения по регистру исчезли.
  3. Проведите документы заново. Платформа запишет движения уже корректно, без дублирования.
  4. Повторите процедуру выгрузки в .dt и загрузки на сервер SQL.

---

Решение 3. Использование утилит физического исправления файловой базы

Иногда обычное перепроведение документов не помогает, так как поврежден сам индекс или структура файла 1CD на физическом уровне. В этом случае перед выгрузкой в SQL необходимо провести комплексное обслуживание файловой базы.

Выполним процедуру лечения по шагам:

  1. Обязательно сделайте резервную копию файла 1Cv8.1CD! Любые утилиты исправления могут безвозвратно удалить поврежденные данные.
  2. Перейдите в каталог установки вашей технологической платформы (обычно это C:\Program Files\1cv8\8.3.XX.XXXX\bin\) и запустите утилиту проверки физической целостности chdbfl.exe.
  3. Укажите путь к вашему файлу базы данных, установите флаг «Реконструировать поврежденные таблицы» и запустите проверку. Утилита исправит физические несоответствия файловой системы.
  4. После этого откройте Конфигуратор и запустите процедуру «Тестирование и исправление» (Администрирование — Тестирование и исправление).
  5. Для исправления логической уникальности обязательно выберите следующие параметры:
    • Реиндексация таблиц информационной базы (перестраивает индексы);
    • Реструктуризация таблиц информационной базы (физически пересоздает таблицы, отбрасывая или корректируя записи с нарушенной уникальностью);
    • Пересчет итогов.
  6. По завершении тестирования повторите попытку переноса базы в СУБД MS SQL.

---

Решение 4. Временное отключение уникального индекса в MS SQL (для экспертов)

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

  1. На сервере MS SQL временно отключают создание уникального индекса с помощью создания DDL-триггера или изменения настроек индексации для конкретной таблицы.
  2. Выполняют загрузку базы из файла .dt. Загрузка завершается успешно, так как SQL Server не пытается принудительно создать уникальный индекс при импорте.
  3. С помощью SQL-запросов к таблице (например, DELETE FROM dbo._AccumRgT22706 ...) находят и физически удаляют одну из дублирующихся строк.
  4. Активируют уникальный индекс обратно.

Важно: Этот метод является экстремальным и может нарушить логическую целостность данных с точки зрения платформы 1С. Рекомендуется использовать первые три метода как наиболее безопасные и документированные производителем.

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

← На главную