Перенос большой базы данных 1С из файлового варианта в клиент-серверный (MS SQL или PostgreSQL) часто сопровождается ошибкой Попытка вставки неуникального значения в уникальный индекс. Эта проблема возникает, когда в файловой базе, которая исторически менее строга к целостности данных, накопились «дубли» — записи, которые логически ошибочны, но физически присутствуют в таблицах. Рассмотрим, как проанализировать эту ситуацию и устранить причину ошибки.
В файловой версии платформы 1С индексы не всегда проверяются на строгую уникальность при каждой записи. Однако при загрузке в SQL-сервер платформа пытается создать уникальные индексы для каждой таблицы (например, для табличных частей документов). Если в таблице _Document133_VT3144 обнаруживаются две строки с одинаковым ключом, SQL-сервер прерывает процесс, выдавая ошибку с кодом 1505. Важно понимать, что стандартное тестирование и исправление (ТиИ) в конфигураторе часто не видит эти дубли, так как они могут быть корректны с точки зрения прикладной логики, но недопустимы для архитектуры СУБД.
Чтобы решить проблему, нам необходимо найти конкретные записи, вызывающие конфликт. Сначала определим, о какой таблице идет речь в сообщении об ошибке. В примере это таблица _Document133_VT3144.
Для работы с PostgreSQL воспользуемся SQL-запросом. Нам нужно преобразовать идентификатор из сообщения об ошибке в понятный для СУБД формат. Используем функцию encode для поиска дубликатов:
SELECT * FROM _document133_vt3144
WHERE encode(_document133_idrref, 'hex') = 'a109001a4d4d010111dcaef25b8f25a2';
Этот запрос выведет все строки, которые имеют повторяющийся ключ. Если вы обнаружили, что запрос возвращает две или более идентичные строки, значит, именно они блокируют процесс загрузки базы.
Когда мы нашли «виновников», нам необходимо удалить одну из дублирующихся строк. Самый безопасный способ сделать это в PostgreSQL — использовать курсор, чтобы гарантированно удалить только одну запись:
DECLARE cursor1 CURSOR FOR
SELECT * FROM _document133_vt3144
WHERE encode(_document133_idrref, 'hex') = 'a109001a4d4d010111dcaef25b8f25a2';
FETCH FORWARD 1 FROM cursor1;
DELETE FROM _document133_vt3144 WHERE CURRENT OF cursor1;
После удаления дублирующей строки рекомендуется повторно выполнить проверку запросом SELECT, чтобы убедиться, что дубликатов больше не осталось.
Если вы не уверены, какой именно документ соответствует найденной ссылке, можно воспользоваться внутренними механизмами платформы для преобразования данных. Вы можете использовать функции ЗначениеВСтрокуВнутр и ЗначениеИзСтрокиВнутр.
Рассмотрим алгоритм поиска документа:
ЗначениеИзСтрокиВнутр.Это позволит вам получить объект Ссылка, который можно открыть в режиме 1С:Предприятие для анализа содержимого документа, если это необходимо для ручного исправления логики.
При переходе на SQL-сервер учитывайте следующие критические моменты:
Date, возможно, в вашей базе присутствуют «пустые» даты, которые SQL интерпретирует как NULL или внедиапазонные значения (ранее 1753 года). В этом случае помогает настройка смещения дат в консоли администрирования 1С.UTF8) и системной локали, чтобы избежать повреждения текстовых данных и появления «кракозябр» после восстановления из дампа.Регулярно проводите профилактическое тестирование целостности данных в файловой базе перед началом миграции. Использование специализированных внешних обработок для поиска битых ссылок и дублей в табличных частях — лучший способ обезопасить себя от подобных инцидентов при переходе на SQL.