При проведении документов в системе 1С:Предприятие пользователи иногда сталкиваются с критической ошибкой: «Попытка вставки неуникального значения в уникальный индекс». Эта проблема блокирует работу с конкретными объектами и часто указывает на серьезные расхождения между логикой приложения и физическим состоянием базы данных в Microsoft SQL Server. В данной статье мы детально разберем, почему возникает эта ошибка, как локализовать поврежденную таблицу и какие шаги предпринять для восстановления работоспособности базы.
Прежде всего, проанализируем текст сообщения об ошибке. Обычно он выглядит следующим образом:
Microsoft SQL Server Native Client 11.0: Не удается вставить повторяющуюся строку ключа в объект "dbo._AccumRg6649" с уникальным индексом "_AccumRg6649_ByPeriod_TRN".
Рассмотрим, что означают эти данные:
_AccumRg указывает на то, что это таблица регистра накопления.ByPeriod_TRN означает, что индекс построен по полям Период, Регистратор и Номер строки.Важное замечание по датам: Если вы видите год 4018, не пугайтесь. Платформа 1С хранит даты в SQL со смещением 2000 лет (если эта опция включена при создании базы). Таким образом, дата «ноя 16 4018» соответствует 16 ноября 2018 года.
Чтобы понять, какому объекту метаданных соответствует таблица _AccumRg6649, воспользуемся методом ПолучитьСтруктуруХраненияБазыДанных() в консоли запросов или программно, либо выполним поиск в таблице DBSchema.
Иногда ошибка вызвана реальным наличием дублей, которые появились из-за сбоя транзакции или некорректной работы программного кода. Для выявления таких записей мы можем выполнить прямой SQL-запрос к базе данных. Проанализируем структуру запроса, который поможет найти строки с одинаковыми ключевыми полями (Период, Регистратор, Номер строки):
SELECT * FROM _AccumRg6649 Acc (NOLOCK)
INNER JOIN (
SELECT
_Period,
_RecorderTRef,
_RecorderRRef,
_LineNo
FROM _AccumRg6649 (NOLOCK)
GROUP BY
_Period,
_RecorderTRef,
_RecorderRRef,
_LineNo
HAVING COUNT(*) > 1
) doubles
ON doubles._Period = Acc._Period
AND doubles._RecorderTRef = Acc._RecorderTRef
AND doubles._RecorderRRef = Acc._RecorderRRef
AND doubles._LineNo = Acc._LineNo
Если этот запрос возвращает результат, значит, в таблице действительно присутствуют физические дубли. Однако бывает ситуация, когда запрос не находит дублей, но ошибка при записи всё равно возникает. Это верный признак повреждения самого индекса (логической коррупции данных).
Если SQL-запросы не выявляют дублей, а 1С продолжает жаловаться на уникальность, причина может крыться в ошибках оперативной памяти сервера или сбоях дисковой подсистемы. В этом случае индекс «думает», что значение есть, хотя в данных его нет (или наоборот).
Рассмотрим шаги по проверке и исправлению базы средствами SQL Server:
DBCC CHECKDB ('Имя_Вашей_Базы') WITH NO_INFOMSGS, ALL_ERRORMSGS;.DBCC CHECKDB ('Имя_Вашей_Базы', REPAIR_REBUILD);.REPAIR_ALLOW_DATA_LOSS, однако помните, что это может привести к удалению части записей.Как показывает практика (сообщение 10 в обсуждении), часто причиной является сбой серверной памяти (ECC). Если вы столкнулись с подобным, обязательно проверьте логи системных событий Windows на наличие аппаратных ошибок памяти.
Иногда достаточно просто «перестроить» индексы, чтобы SQL Server пересчитал дерево уникальных ключей. Это более безопасная процедура, чем полное исправление базы. Разберем выполнение команды:
ALTER INDEX ALL ON _AccumRg6649 REBUILD;
Эта команда полностью пересоздает все индексы для указанной таблицы. Если ошибка была вызвана «фантомными записями» или нарушением логической связности индекса, после выполнения REBUILD проведение документа должно пройти успешно.
Если техническая проверка базы не выявила проблем, следует проанализировать модуль объекта документа, на котором возникает ошибка. В 1С:Предприятии 8 уникальность в регистре накопления обеспечивается связкой Регистратор + НомерСтроки.
Проанализируем возможные ошибки в коде:
Набор.Записывать = Истина, и при этом номера строк (LineNo) заполняются вручную, алгоритм может по ошибке присвоить двум разным строкам один и тот же номер.Не стоит забывать и о кешировании на стороне сервера приложений 1С. Фантомные ошибки уникальности могут быть вызваны некорректным состоянием сеанса в процессе rphost.
Для устранения этой вероятности выполните следующие действия:
srvinfo/reg_1541/snccntx... (кеш сеансов).В завершение разберем стандартный инструмент 1С — «Тестирование и исправление информационной базы». В Конфигураторе выберите пункт «Администрирование» — «Тестирование и исправление».
Нас интересуют следующие флаги:
_T). Пересчет итогов полностью очищает и заново заполняет эти таблицы на основе записей регистра.Резюме: При возникновении ошибки «Попытка вставки неуникального значения» мы сначала проверяем физическое наличие дублей в SQL, затем исключаем аппаратные сбои (память/диск) через CHECKDB и REBUILD, и только после этого приступаем к отладке программного кода 1С.