Как перенести базу 1С с файлового варианта на SQL при возникновении ошибок неуникальности данных

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

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

В данной статье мы разберем нестандартный, но эффективный метод обхода этой проблемы с помощью механизмов Распределенной Информационной Базы (РИБ), а также рассмотрим сопутствующие инструменты исправления данных. Мы проанализируем ситуацию, когда стандартное Тестирование и исправление (ТИИ) не помогает, и выработаем пошаговый алгоритм действий.

Почему возникает ошибка уникальности и как ее диагностировать?

Перед тем как приступать к сложным схемам переноса, нам необходимо понять природу ошибки. Файловая база в процессе долгой эксплуатации, особенно при объемах свыше 10-20 Гб (как в случае с «1С:Розница»), может накапливать логические ошибки в таблицах индексов. Чаще всего страдают регистры сведений и регистры накопления.

Для диагностики выполним следующие шаги:

  1. Проанализируем текст ошибки SQL. Обычно он содержит имя таблицы, например _InfoReg1234.
  2. Выясним, какому объекту метаданных соответствует эта таблица. Для этого в консоли запросов или в обработке выполним метод:
    
    Структура = ПолучитьСтруктуруХраненияБазыДанных();
    // Перебор структуры для поиска нужной таблицы
    
  3. Воспользуемся утилитой chdbfl.exe, которая находится в папке bin вашей платформы. Это обязательный этап перед любой выгрузкой .dt. Рассмотрим ситуацию: если утилита находит ошибки и исправляет их, попробуем повторную выгрузку.

Метод переноса данных через создание начального образа РИБ

Если стандартные средства исправления не помогают, и загрузка .dt по-прежнему «валится», рассмотрим стратегию использования РИБ. Идея заключается в том, чтобы заставить систему переписать данные объектно, а не «слепком» всей базы. При объектной записи система часто может игнорировать или исправлять мелкие огрехи файлового движка.

Разберем пошаговый алгоритм реализации этой идеи:

  1. Подготовка исходной базы: Сделаем полную копию файловой базы. В этой копии нам нужно убедиться, что база является «главной» для самой себя в контексте РИБ. Если она уже является подчиненным узлом, используем обработку для снятия признака подчиненности (метод ПланыОбмена.УстановитьГлавныйУзел(Неопределено)).
  2. Создание нового узла: В плане обмена, по которому работает ваша конфигурация (например, «По магазинам» в Рознице), создадим новый подчиненный узел.
  3. Создание начального образа на SQL: Это ключевой момент. Вместо того чтобы создавать файловый образ, выгружать его в .dt и загружать в SQL, мы можем создать образ сразу на сервере. В меню «Операции» (или через функции для технического специалиста) выберем команду «Создать начальный образ». В появившемся окне выберем вариант «На сервере 1С:Предприятия» и укажем параметры создаваемой SQL-базы.
  4. Процесс наполнения: Платформа начнет создавать структуру таблиц в SQL и пообъектно копировать туда данные. Если в процессе возникнет ошибка на конкретном объекте, система укажет на него, что позволит нам точечно удалить проблемную запись в исходной базе.

Тонкая настройка кода для успешной загрузки

При переносе данных через РИБ или XML-выгрузку крайне важно, чтобы при записи объектов не срабатывали лишние проверки или алгоритмы, которые могут изменить данные «на лету» или заблокировать загрузку. Рассмотрим, как это контролируется в коде 1С.

Проанализируем типовой механизм использования свойства ОбменДанными.Загрузка. Во всех процедурах ПередЗаписью или ПриЗаписи в модулях объектов должен стоять следующий блок кода:


Процедура ПередЗаписью(Отказ)
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;
    
    // Далее следует логика, которая не должна выполняться при переносе
КонецПроцедуры

Если вы используете нетиповую конфигурацию или вносили изменения в типовую, обязательно проверьте наличие этого условия в дописанных объектах. Это гарантирует, что данные будут перенесены «как есть», без выполнения проверок уникальности, заложенных в программном коде (но не в структуре SQL).

Альтернативный вариант: Выгрузка и загрузка через XML

Рассмотрим еще один надежный способ — использование универсальной обработки «Выгрузка и загрузка данных XML». Этот метод часто оказывается более гибким, чем РИБ, так как позволяет переносить данные частями.

Алгоритм действий будет следующим:

  1. Создадим пустую базу на SQL с той же конфигурацией (через выгрузку/загрузку .cf файла).
  2. В исходной файловой базе запустим обработку «ВыгрузкаЗагрузкаДанныхXML.epf».
  3. Выполним выгрузку данных. Важный совет: не пытайтесь выгрузить все 20 Гб одним файлом. Выгружайте справочники отдельно, а регистры и документы — по периодам или по видам метаданных.
  4. Если при загрузке какого-то конкретного регистра (например, «Цены номенклатуры») возникает ошибка неуникальности, мы можем просто исключить этот регистр из общего переноса, почистить его в исходной базе и перенести позже.

Финальная «перепривязка» узла после миграции

Предположим, вы успешно перенесли данные в новую базу на SQL методом создания начального образа. Теперь эта база является подчиненным узлом по отношению к вашей временной «копии-мастеру». Чтобы вернуть базу в общую структуру РИБ предприятия, нам нужно выполнить перепривязку.

Рассмотрим, как правильно изменить главного узла:

  1. В новой SQL-базе запустим обработку, выполняющую код: ПланыОбмена.УстановитьГлавныйУзел(УзелСсылкаНаНастоящуюЦБ);
  2. Важно понимать, что после этого номера сообщений обмена могут не совпадать. Нам потребуется программно установить номера принятого и отправленного сообщения в соответствии с данными, которые хранятся в Центральной Базе (ЦБ). Проанализируем состояние номеров в ЦБ и с помощью стандартной обработки «Регистрация изменений для обмена» установим нужные значения.
  3. Обязательно очистим регистрацию изменений в новой SQL-базе, если мы не хотим, чтобы она при первом же обмене попыталась выгрузить все свои данные обратно в центр.

Резюме и рекомендации

Подведем итоги нашего исследования. Перенос базы 1С с файловой версии на SQL через механизмы РИБ — это рабочая и зачастую спасительная идея, когда стандартный механизм .dt не справляется из-за ошибок уникальности.

Основные выводы:

Помните, что база размером 20 Гб в формате .1cd находится на пределе стабильности файлового режима. Переход на SQL не только решит текущую проблему с индексами, но и значительно повысит производительность и надежность вашей системы «1С:Розница».

← На главную