При обновлении конфигурации или выполнении реструктуризации базы данных 1С на платформе Microsoft SQL Server специалисты часто сталкиваются с критической ошибкой: «Нарушено условие уникальности данных. Попытка вставки неуникального значения в уникальный индекс». Особенно неприятно, когда ошибка возникает в журнале документов, так как стандартное «Тестирование и исправление» (ТиИ) не всегда способно выявить проблему в данных, которые мешают создать новый индекс. Для глубокого понимания состояния системы в такие моменты полезно проанализировать SQL сервер глазами 1С-ника, что поможет выявить скрытые причины блокировок и конфликтов.
В этой статье мы подробно разберем, почему возникает эта ошибка, как расшифровать сообщение SQL-сервера и какими методами можно очистить базу от дублей, препятствующих обновлению.
Проанализируем ситуацию: ошибка происходит при выполнении инструкции CREATE UNIQUE INDEX. Суффикс NG в имени таблицы (например, _DocumentJournal28036NG) указывает на то, что 1С создает временную («новую») таблицу для реструктуризации данных. Платформа пытается перенести данные из старой таблицы в новую и создать уникальный индекс, но обнаруживает, что в данных уже есть дубли. В обычной эксплуатации адаптивное обновление индексов MS SQL позволяет поддерживать производительность, но при структурных изменениях наличие дублей становится блокирующим фактором.
Выясним причину появления дублей. Чаще всего это происходит в следующих случаях:
_DocumentRRef (ссылки документа) недопустимо, так как журнал должен содержать строго одну запись на один документ.Посмотрим на пример сообщения об ошибке: Повторяющееся значение ключа: (0, 0x000002aa, 0x818fc8d3a384789d11eb6239840abf1b). Эти данные позволяют нам точно найти проблемный документ без долгого поиска. Разберем, что значат эти поля в контексте журнала документов:
_Marked (признак удаления). В данном случае дубль среди неудаленных документов._DocumentTRef — внутренний идентификатор типа метаданных (какой именно это документ: Приходная накладная, Заказ и т.д.)._DocumentRRef — уникальный идентификатор (GUID) конкретного документа.Чтобы понять, какой таблице соответствует имя _DocumentJournal28036, воспользуемся встроенным методом 1С. Чтобы сделать работу с ним быстрее и нагляднее, можно использовать специальную обработку, раскрывающую структуру хранения базы данных — для этого подойдёт анализ структуры и физических таблиц базы данных.
Структура = ПолучитьСтруктуруХраненияБазыДанных();
// Переберем структуру, чтобы найти имя таблицы журнала
Проанализируем данные в SQL Management Studio. Чтобы найти записи, которые мешают созданию уникального индекса, нам нужно сгруппировать данные по полям, входящим в этот индекс. Для журналов документов это обычно поля ссылки и типа документа.
Рассмотрим пример запроса для поиска дублей:
SELECT _DocumentTRef, _DocumentRRef, COUNT(*) as Counter
FROM _DocumentJournal28036
GROUP BY _DocumentTRef, _DocumentRRef
HAVING COUNT(*) > 1
Если запрос вернул строки, значит, в вашей таблице действительно есть записи-дубликаты. Чтобы увидеть их детально и понять, чем они отличаются (например, датой или номером), используем вложенный запрос:
SELECT *
FROM _DocumentJournal28036
WHERE _DocumentRRef IN (
SELECT _DocumentRRef
FROM _DocumentJournal28036
GROUP BY _DocumentTRef, _DocumentRRef
HAVING COUNT(*) > 1
)
ORDER BY _DocumentRRef
Рассмотрим несколько стратегий исправления ситуации. Отметим, что если аналогичные симптомы наблюдаются в других объектах метаданных, может потребоваться исправление ошибки неуникальности в регистре сведений.
Вариант А: Удаление лишних записей в SQL
Если вы нашли конкретные дубли, можно удалить одну из записей вручную через SQL, оставив только актуальную. Важно: перед любыми прямыми манипуляциями с SQL-таблицами обязательно создайте резервную копию базы данных!
Пример удаления (подставьте свой _DocumentRRef из ошибки):
DELETE FROM _DocumentJournal28036
WHERE _DocumentRRef = 0x818FC8D3A384789D11EB6239840ABF1B
-- Внимание: этот запрос удалит все записи с этим GUID.
-- Если нужно оставить одну, добавьте условие по другим полям.
Вариант Б: Полная очистка журнала (самый надежный способ)
Если дублей много и база не позволяет выгрузить её в файловый вариант, мы можем прибегнуть к радикальному, но эффективному методу очистки таблицы журнала. Журнал документов в 1С — это вторичные данные, которые могут быть восстановлены программно.
Разберем алгоритм действий:
TRUNCATE TABLE _DocumentJournal28036.Объект.Записать()) все документы, входящие в этот журнал — в этом поможет групповая обработка массовой перезаписи и проведения документов. Проверить корректность восстановления данных поможет универсальный журнал и реестр документов, который позволяет видеть движения и реквизиты всех типов документов в одном интерфейсе.Иногда попытка вставки неуникального значения может быть следствием повреждения самих файлов базы данных или индексов на уровне файловой системы. Проанализируем состояние базы командой:
DBCC CHECKDB ('Имя_Вашей_Базы') WITH NO_INFOMSGS, ALL_ERRORMSGS
Если команда обнаружит ошибки целостности, то проблему нужно решать через восстановление базы (REPAIR_ALLOW_DATA_LOSS), а не просто удалением дублей в 1С. Чтобы минимизировать риск появления таких ошибок в будущем, должна быть внедрена грамотная инструкция по настройке регламентных операций MS SQL SERVER под 1С.
Мы выяснили, что ошибка уникальности в журнале документов чаще всего вызвана логическим дублированием ссылок на документы. Для исправления ситуации необходимо определить имя таблицы через ПолучитьСтруктуруХраненияБазыДанных(), найти дубли через GROUP BY в SQL и либо точечно их удалить, либо полностью очистить таблицу с последующим перепроведением документов. Это позволит успешно завершить обновление даже на очень крупных базах данных.