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

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

При миграции информационной базы из файлового варианта в клиент-серверный или при развертывании базы из файла выгрузки .dt администраторы часто сталкиваются с ошибкой HRESULT=80040E2F. Система сообщает о невозможности создания уникального индекса из-за дублирующихся ключей. Рассмотрим подробно, почему это происходит и как устранить проблему, сохранив целостность данных.

Разбор технической сути ошибки

Проанализируем текст ошибки, представленный в системном сообщении. В нем указано имя объекта: dbo._AccRgAT2674. Для специалиста 1С это имя является «говорящим»:

  1. Префикс _AccRg означает, что данные принадлежат Регистру бухгалтерии (Accounting Register).
  2. Суффикс AT (Aggregates/Totals) указывает на то, что это таблица итогов данного регистра.
  3. Числовой идентификатор 2674 соответствует внутреннему номеру объекта в конкретной конфигурации.

Суть проблемы заключается в том, что в исходной базе (в файле .dt) содержатся записи, которые с точки зрения SQL Server являются идентичными для ключевых полей индекса. При попытке массовой вставки данных (Bulk Insert) SQL Server пытается построить уникальный индекс, но натыкается на дубль и прерывает операцию.

Выясняем причину появления даты «4016 год»

В тексте ошибки часто фигурирует странная дата, например, 4016-12-01. Разберем, откуда она берется. В платформе 1С реализован механизм «смещения дат» (обычно на 2000 лет) для корректной работы с минимальными значениями дат в различных СУБД. Значение в пятом тысячелетии может возникнуть по нескольким причинам:

Метод 1: Полный пересчет итогов (Рекомендуемый)

Поскольку ошибка локализована в таблице итогов (AT), а не в таблице самих движений, самым простым и эффективным способом будет полная очистка и пересчет этих данных. Итоги — это производные данные, которые 1С может восстановить на основании первичных записей регистра. Выполним следующие шаги в исходной базе (до выгрузки в .dt):

  1. Откроем базу в режиме «1С:Предприятие».
  2. Перейдем в раздел «Все функции» (или «Функции для технического специалиста») — «Стандартные» — «Управление итогами».
  3. Выберем соответствующий регистр бухгалтерии.
  4. Снимем флаг «Использование итогов» и «Использование текущих итогов».
  5. Установим период рассчитанных итогов на максимально раннюю дату (например, на начало времен).
  6. Выполним применение изменений. Это очистит физическую таблицу _AccRgAT.
  7. После этого сделаем новую выгрузку в файл .dt.
  8. Загрузим полученный файл в SQL. Ошибка должна исчезнуть, так как таблица итогов будет пустой.
  9. В загруженной базе SQL снова зайдем в «Управление итогами» и включим их, запустив полный пересчет.

Метод 2: Проверка физической целостности (chdbfl.exe)

Если метод с итогами не помог, вероятно, повреждена сама структура таблиц в файле .1CD. Стандартное «Тестирование и исправление» из конфигуратора может не справиться, так как оно работает на логическом уровне. Воспользуемся утилитой chdbfl.exe, которая находится в папке bin установленной платформы.

Рассмотрим порядок действий:

  1. Обязательно создадим резервную копию файла базы данных.
  2. Запустим chdbfl.exe.
  3. Укажем путь к файлу 1Cv8.1CD.
  4. Установим галочку «Исправлять обнаруженные ошибки».
  5. Нажмем «Выполнить». Утилита проверит физические страницы данных и устранит несоответствия в индексах и структурах таблиц.

После завершения работы утилиты следует снова попробовать выполнить выгрузку и загрузку в SQL.

Метод 3: Программный поиск дублей через обработку

Если база имеет огромный объем и пересчет итогов занимает слишком много времени, можно попытаться найти и удалить конкретную запись-дубль. Для этого нам потребуется написать небольшую обработку, которая проанализирует записи регистра.

Посмотрим на пример логики поиска проблемных записей:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Регистр.Период,
    |   Регистр.Счет,
    |   Регистр.Организация,
    |   КОЛИЧЕСТВО(*) КАК КоличествоДублей
    |ИЗ
    |   РегистрБухгалтерии.Хозрасчетный.Итоги КАК Регистр
    |СГРУППИРОВАТЬ ПО
    |   Регистр.Период,
    |   Регистр.Счет,
    |   Регистр.Организация
    |ИМЕЮЩИЕ
    |   КОЛИЧЕСТВО(*) > 1";

Результат = Запрос.Выполнить();
Если Не Результат.Пустой() Тогда
    Выборка = Результат.Выбрать();
    Пока Выборка.Следующий() Цикл
        Сообщить("Найден дубль по счету " + Выборка.Счет + " на дату " + Выборка.Период);
    КонецЦикла;
КонецЕсли;

Важно помнить, что в уникальный индекс таблицы итогов входит множество полей (субконто, измерения, валюты). В запросе выше приведен упрощенный пример. Чтобы найти точный дубль, нужно добавить в группировку все поля, которые перечислены в ошибке SQL (те самые <NULL> и 0x88d5... в скобках сообщения).

Метод 4: Использование внешних утилит (Tool1CD)

В самых сложных случаях, когда база не открывается ни в режиме Предприятия, ни в режиме Конфигуратора, можно воспользоваться неофициальной утилитой Tool1CD для прямого чтения файла .1CD.

Проанализируем ситуацию по шагам:

  1. Откроем базу в Tool1CD.
  2. Найдем таблицу _AccRgAT[номер].
  3. Отсортируем данные по колонке с датой (обычно это _Period).
  4. Найдем записи с некорректными датами (4016 год).
  5. Удалим эти записи непосредственно из файла (соблюдая предельную осторожность).

Внимание: Прямое редактирование таблиц — это крайняя мера, которая может привести к окончательной порче базы данных. Всегда работайте только с копией!

Почему «Тестирование и исправление» (ТиИ) может быть бесполезно?

Как отмечают участники обсуждения, процедура ТиИ часто не решает проблему CREATE UNIQUE INDEX. Это происходит потому, что при установке флага «Реиндексация таблиц» платформа пытается выполнить ту же самую операцию, что и SQL Server при загрузке — создать индекс. Если в данных уже есть дубль, создание индекса прервется с ошибкой еще до того, как ТиИ перейдет к этапу «Проверка логической целостности», на котором теоретически дубли могли быть вычищены.

Резюме

Для успешного решения проблемы мы рекомендуем начинать с Метода 1 (Отключение и очистка итогов). Это наиболее безопасный и «штатный» способ, который в 90% случаев устраняет ошибки в таблицах _AccRgAT и _AccumRgAT. Если же ошибка возникает в таблицах движений (без суффикса AT), используйте chdbfl.exe и программный поиск дублей по регистратору.

← На главную