При активной доработке конфигурации 1С 7.7, работающей в связке с Microsoft SQL Server, разработчики нередко сталкиваются с аварийным завершением работы Конфигуратора. Типичная ситуация: создается новый журнал документов, добавляются новые графы отбора или изменяется состав реквизитов, после чего при сохранении метаданных платформа зависает и выдает ошибку SQL State 2000: The CREATE UNIQUE INDEX statement terminated because a duplicate key was found. The object name dbo._1SCRDOC and the index name CHILD. Выясним причину этой неполадки и подробно рассмотрим шаги по ее устранению.
Таблица _1SCRDOC (служебная таблица «Ссылки документов») отвечает за хранение информации о перекрестных ссылках между документами. Она обеспечивает функционирование дерева подчиненных документов, быстрое построение журналов и работу механизмов отбора по графам. Основной уникальный индекс этой таблицы носит наименование CHILD и формируется по трем полям:
CHILDID — идентификатор подчиненного документа (соответствует полю IDDOC из таблицы _1SJOURN);MDID — идентификатор объекта метаданных (графы отбора, общего реквизита или 0 для стандартной связи подчинения);PARENTVAL — строковое представление родительского документа или значения реквизита отбора.В момент добавления нового журнала или графы отбора Конфигуратор инициирует реструктуризацию таблицы и пытается заново пересоздать индекс с требованием уникальности. Если в таблице уже присутствуют строки с полностью идентичной комбинацией CHILDID + MDID + PARENTVAL, сервер СУБД отвергает создание индекса, и сессия 1С аварийно завершается.
Проанализируем основные причины появления дубликатов в базе данных:
Самый правильный путь исправления — локализовать документы, породившие дублирующие записи, и исправить сами данные. Для поиска проблемных документов обратимся напрямую к SQL Server Management Studio (или Query Analyzer) и выполним следующий аналитический запрос:
SELECT distinct
_1sjourn.docno,
_1sjourn.DATE_TIME_IDDOC
FROM [dbo].[_1SCRDOC]
LEFT JOIN [dbo].[_1SJOURN]
ON [_1SCRDOC].childid = [_1SJOURN].IDDOC
GROUP BY PARENTVAL, CHILDID, MDID, DOCNO, DATE_TIME_IDDOC
HAVING COUNT(*) > 1
ORDER BY DATE_TIME_IDDOC;
Разберем полученный результат. Запрос вернет номер проблемного документа (DOCNO) и его внутреннюю позицию с идентификатором (DATE_TIME_IDDOC). По этим данным мы легко найдем документ в пользовательском режиме 1С.
Чтобы понять, какая именно графа отбора или реквизит вызвали сбой, посмотрим на значение MDID из текста ошибки или расширенного запроса. Откроем файл словаря структуры базы данных 1Cv7.DD (или 1Cv7.DDS) в каталоге информационной базы через текстовый редактор и выполним поиск по числовому значению MDID. Это позволит определить конкретный реквизит или графу отбора и скорректировать метаданные так, чтобы исключить дублирование данных в будущем.
После локализации документов достаточно открыть их в режиме «1С:Предприятие», проверить заполнение реквизитов, очистить лишние дублирующие строки и перепровести документы. Повторный запуск проверочного запроса должен вернуть пустой результат.
Если база данных заблокирована ошибкой сохранения структуры и зайти в пользовательский режим для перепроведения документов невозможно, применим временный обходной путь через редактирование файла структуры базы данных.
Разберем последовательность действий:
1Cv7.DDS и откроем его любым текстовым редактором._1SCRDOC и блок описания индексов #----Indexes------.CHILD. В строке параметров индекса найдем флаг уникальности и временно изменим его значение на 0 (снятие требования уникальности).Важное предупреждение: изменение флага уникальности в 1Cv7.DDS является лишь временной мерой для получения доступа к данным. При следующем изменении метаданных Конфигуратор заново перезапишет файл 1Cv7.DDS из файла 1Cv7.MD, восстановит требование уникальности индекса и ошибка повторится, если дубликаты не были устранены в самих таблицах.
Если документов с дубликатами слишком много или они относятся к закрытым периодам, которые нежелательно перепроводить, устраним дубликаты непосредственно на стороне СУБД с помощью инструкции обобщенного табличного выражения (CTE):
WITH Duplicates AS (
SELECT ROW_ID,
ROW_NUMBER() OVER (
PARTITION BY CHILDID, MDID, PARENTVAL
ORDER BY ROW_ID
) AS RowNum
FROM _1SCRDOC
)
DELETE FROM Duplicates WHERE RowNum > 1;
Этот скрипт оставит ровно одну уникальную запись для каждой связки CHILDID + MDID + PARENTVAL и удалит все лишние повторы. После выполнения запроса вернемся в Конфигуратор и завершим операцию сохранения структуры — уникальный индекс CHILD будет успешно построен.
Таблица _1SCRDOC содержит исключительно производные, вычисляемые данные, которые можно полностью восстановить штатными механизмами платформы. Если в таблице накопилось множество некорректных связей из-за сбоев прошлых лет, наиболее чистым решением является ее полная переиндексация с нуля.
Выполним процедуру по шагам:
TRUNCATE TABLE _1SCRDOC;
В процессе пересчета служебных данных платформа последовательно обработает все документы информационной базы и заново сформирует содержимое таблицы _1SCRDOC. В результате все дубликаты будут исключены, структура таблицы станет полностью консистентной, а индекс CHILD успешно зафиксируется со статусом уникальности.