Обнаружены дублирующиеся ключи в уникальных индексах таблицы 1с как исправить

Обновлено: 06.07.2024

Cannot insert duplicate key row in object

Попытка вставки неуникального значения в уникальный индекс.

Что такое индекс?

Подобно содержанию в книге, индекс в базе данных позволяет быстро искать конкретные сведения в таблице.

Индексы представляют собой структуру, позволяющую выполнять ускоренный доступ к строкам таблицы на основе значений одного или более ее столбцов.
Индекс содержит ключи, построенные из одного или нескольких столбцов таблицы или представления, и указатели, которые сопоставляются с местом хранения заданных данных.
Индексы сокращают объем данных, которые необходимо считать, чтобы возвратить результирующий набор.

Хотя индекс и связан с конкретным столбцом (или столбцами) таблицы, все же он является самостоятельным объектом базы данных.

Индексы таблиц в базе данных 1С:Предприятие создаются неявным образом при создании объектов конфигурации, а также при тех или иных настройках объектов конфигурации.

Физическая сущность индексов в MS SQL Server 2005.

Несмотря на достоинства, индексы так же имеют и ряд недостатков. Первый из них – индексы занимают дополнительное место на диске и в оперативной памяти. Каждый раз когда вы создаете индекс, вы сохраняете ключи в порядке убывания или возрастания, которые могут иметь многоуровневую структуру. И чем больше/длиннее ключ, тем больше размер индекса. Второй недостаток – замедляются операции вставки, обновления и удаления записей.
В среде MS SQL Server 2005 реализовано несколько типов индексов:

  • некластерные индексы;
  • кластерные (или кластеризованные) индексы;
  • уникальные индексы;
  • индексы с включенными столбцами
  • индексированные представления
  • полнотекстовый
  • XML

Уникальный индекс

Уникальность значений в индексируемом столбце гарантируют уникальные индексы. При их наличии сервер не разрешит вставить новое или изменить существующее значение таким образом, чтобы в результате этой операции в столбце появились два одинаковых значения.
Уникальный индекс является своеобразной надстройкой и может быть реализован как для кластерного, так и для некластерного индекса. В одной таблице может существовать один уникальный кластерный и множество уникальных некластерных индексов.
Уникальные индексы следует определять только тогда, когда это действительно необходимо. Для обеспечения целостности данных в столбце можно определить ограничение целостности UNIQUE или PRIMARY KEY, а не прибегать к уникальным индексам. Их использование только для обеспечения целостности данных является неоправданной тратой пространства в базе данных. Кроме того, на их поддержание тратится и процессорное время.

1С:Предприятие 8.1 начиная с версии 8.1 активно использует кластерные уникальные индексы. Это означает, что при конвертации с 8.0 или переходе с 8.1.7 можно получить ошибку неуникального индекса.

ошибка индекса

Если неуникальность заключается в датах с нулевыми значениями, то проблема решается созданием базы с параметром смещения равным 2000.

Что делать?

1. Если проблема загрузкой базы данных, то:

Смещение 200

Если уже база создана со смещением 0, то создайте новую с 2000.

1.4. Для локализации проблемы можно определить данные объекта, загрузка которого не удалась. Для этого надо включить во время загрузки трассировку в утилите Profiler или включите запись втехнологический журнал событий DBMSSQL и EXCP.

1.5. Если доступна узел (планы обменов), то выполнить обмен. Можно также дополнительно перед обменом выполнить пункт 2.3.5

2. Если проблема неуникальности проявляется во время работы пользователей:

2.1. Найти с помощью метода пункта 1.4 проблемный запрос.

2.1.2. Иногда ошибка возникает во время исполнения запросов, например:

2.2. После нахождения проблемного индекса из предыдущего пункта, необходимо найти неуникальную запись.

2.2.1. «Рыба» скрипта для определения неуникальных записей с помощью SQL:
SELECT COUNT(*) Counter, <перечисление всех полей соответствующего индекса> from <имя таблицы>
GROUP BY <перечисление всех полей соответствующего индекса>
HAVING Counter > 1

Перечень полей таблицы:

_Document140_IDRRef, _KeyField, _LineNo1386, _Fld1387, _Fld1388, _Fld1389, _Fld1390, _Fld1391RRef, _Fld1392RRef, _Fld1393_TYPE, _Fld1393_RTRef, _Fld1393_RRRef, _Fld1394,

_Fld1395, _Fld1396RRef, _Fld1397, _Fld1398, _Fld1399RRef, _Fld22260_TYPE, _Fld22260_RTRef, _Fld22260_RRRef, _Fld22261_TYPE, _Fld22261_RTRef, _Fld22261_RRRef

Перед выполнением приведенной ниже процедуры сделайте резервную копию базы данных.
Выполните в MS SQL Server Query Analizer:

select count(*), _Document140_IDRRef, _KeyField
from _Document140_VT1385
group by _Document140_IDRRef, _KeyField
having count(*) > 1

С его помощью узнайте значения колонок _Document140_IDRRef, _KeyField, дублирующихся записей (id, key).

При помощи запроса:

посмотрите на значения других колонок дублирующихся записей.

Если обе записи имеют осмысленные значения и эти значения разные, то исправьте значение _KeyField на уникальное. Для этого определите максимальное занятое значение _KeyField (keymax):

select max(_KeyField)
from _Document140_VT1385
where _Document140_IDRRef = id1

Замените значение _KeyField в одной из повторяющихся записей на правильное:

update _Document140_VT1385
set _KeyField = keymax + 1
where _Document140_IDRRef = id1 and _LineNo1386 = lineno1

Если одна (или обе) из повторяющихся записей имеет очевидно неправильное значение, то ее нужно удалить:

delete from _Document140_VT1385
where _Document140_IDRRef = id1 and _LineNo1386 = lineno1

Если повторяющиеся записи имеют одинаковые значения во всех колонках, то из них нужно оставить одну:

delete from _Document140_VT1385
where _Document140_IDRRef = id1 and _KeyField = key1

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

2.2.3. Второй пример:

SELECT COUNT(*) AS Expr2, _IDRRef AS Expr1, _Description
FROM _Reference8_
GROUP BY _IDRRef, _Description
HAVING (COUNT(*) > 1)

2.3.4 Пример определения неуникальных записей с помощью запроса 1С:Предприятие:

ВЫБРАТЬ Справочник.Ссылка
ИЗ Справочник.Справочник КАК Справочник
СГРУППИРОВАТЬ ПО Справочник.Ссылка
ИМЕЮЩИЕ КОЛИЧЕСТВО(*) > 1

или для бухгалтерии

ВЫБРАТЬ
Подзапрос.Период,
Подзапрос.Регистратор,
<измерения>,
СУММА(Подзапрос.КоличествоЗаписей) КАК КоличествоЗаписей
ИЗ
(ВЫБРАТЬ
Хозрасчетный.Период КАК Период,
Хозрасчетный.Регистратор КАК Регистратор,
<измерения>,
1 КАК КоличествоЗаписей
ИЗ
РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный) КАК Подзапрос

СГРУППИРОВАТЬ ПО
Подзапрос.Период,
Подзапрос.Регистратор,
<измерения>

ИМЕЮЩИЕ
СУММА(Подзапрос.КоличествоЗаписей) > 1

2.3.5 Сделать индекс субд не уникальным. Заксриптовать индекс с помощью Management Studio.

Далее удалить текущий индекс, скорректировать текст и создать скриптом неуникальный индекс.

DETAIL: Key (_fld12396, _period, _recordertref, _recorderrref, _lineno, _kindrref, _correspond)=(0, 2015-05-15 23:59:59, \x000000b5, \xab32001a4d38920e11e523db3c85e9f9, 3, \xb44b334de4c5d19d4d7785e8f75e7abe, 1) is duplicated.

проблема с записью:

Период - 15.05.2015 23:59:59.
Регистратор - ab32001a4d38920e11e523db3c85e9f9
НомерСтроки - 3
Субконто - b44b334de4c5d19d4d7785e8f75e7abe

УИД из значений получается преобразованием:

ТиИ делать пробовали: реиндексацию + реструктуризацию таблиц?


да пробовала.
а что за УИД - Перейти по навигационной ссылке не дает результата.
а, это написать надо?
ИмяСправочника Номенклатура попробовать?! (17) Это значение ссылки из текста запроса.
Я написал, как из этого получить УИ и преобразовать УИ в ссылку. ТиИ делать пробовали: реиндексацию + реструктуризацию таблиц?

В процессе обновления информационной базы произошла критическая ошибка
по причине:
Ошибка SDBL:
Ошибка обновления конфигурации базы данных. Для одного ссылочного кода существует более одной таблицы в базе данных.

Имена таблиц с кодом 32389: InfoRgChngR32389, ReferenceChngR32389
Имена таблиц с кодом 32465: InfoRg32465, ReferenceChngR32465
Имена таблиц с кодом 33035: Reference33035, ReferenceChngR33035
Имена таблиц с кодом 33149: ConstChngR33149, ReferenceChngR33149
Имена таблиц с кодом 33263: InfoRgChngR33263, ReferenceChngR33263
Имена таблиц с кодом 33301: InfoRg33301, ReferenceChngR33301
Имена таблиц с кодом 33377: InfoRgChngR33377, ReferenceChngR33377
Имена таблиц с кодом 33521: Enum33521, ReferenceChngR33521
Имена таблиц с кодом 33542: ConstChngR33542, ReferenceChngR33542
Имена таблиц с кодом 33564: InfoRgChngR33564, ReferenceChngR33564
Имена таблиц с кодом 33736: ConstChngR33736, ReferenceChngR33736
Имена таблиц с кодом 33878: DocumentJournal33878, ReferenceChngR33878
Имена таблиц с кодом 33881: Const33881, ReferenceChngR33881
Имена таблиц с кодом 34045: InfoRgChngR34045, ScheduledJobs34045
Имена таблиц с кодом 34046: InfoRg34046, ScheduledJobs34046
Имена таблиц с кодом 34121: Enum34121, ReferenceChngR34121
Имена таблиц с кодом 34275: Enum34275, ScheduledJobs34275
Для исправления проблемы вы можете обратиться в службу технической поддержки.

Поврежден заголовок файла базы данных
Повреждена таблица размещения внутреннего файла <Данные таблицы '_ACCUMRGT24795'>
Повреждена таблица размещения внутреннего файла <Данные таблицы '_ACCUMRGT24823'>
Повреждена таблица размещения внутреннего файла <Данные таблицы '_ACCUMRGT24901'>
Повреждена таблица размещения внутреннего файла <Данные таблицы '_ACCUMRGT24923'>
Повреждена таблица размещения внутреннего файла <Данные таблицы '_ACCUMRGT25424'>
Повреждена таблица размещения внутреннего файла <Данные таблицы '_ACCUMRGT25597'>
Повреждена таблица размещения внутреннего файла <Данные таблицы '_ACCUMRGT25609'>
Повреждена таблица размещения внутреннего файла <Данные таблицы '_ACCUMRGT25623'>
Повреждена таблица размещения внутреннего файла <Данные таблицы '_ACCRGAT21337'>
Обнаружены дублирующиеся ключи в уникальных индексах таблицы '_ACCUMRGT24589'
Обнаружены дублирующиеся ключи в уникальных индексах таблицы '_ACCUMRGT24611'
Повреждены данные таблицы '_ACCUMRGT24795'. Восстановлено 3777618 из 3780974 записей.
Обнаружены дублирующиеся ключи в уникальных индексах таблицы '_ACCUMRGT24795'
Повреждены данные таблицы '_ACCUMRGT24823'. Восстановлено 3766680 из 3770063 записей.
Обнаружены дублирующиеся ключи в уникальных индексах таблицы '_ACCUMRGT24823'
Повреждены данные таблицы '_ACCUMRGT24901'. Восстановлено 1686797 из 1689042 записей.
Обнаружены дублирующиеся ключи в уникальных индексах таблицы '_ACCUMRGT24901'
Повреждены данные таблицы '_ACCUMRGT24923'. Восстановлено 1685425 из 1687696 записей.
Обнаружены дублирующиеся ключи в уникальных индексах таблицы '_ACCUMRGT24923'
Обнаружены дублирующиеся ключи в уникальных индексах таблицы '_ACCUMRGT25356'
Повреждены данные таблицы '_ACCUMRGT25424'. Восстановлено 863054 из 863072 записей.
Обнаружены дублирующиеся ключи в уникальных индексах таблицы '_ACCUMRGT25424'
Повреждены данные таблицы '_ACCUMRGT25597'. Восстановлено 554558 из 554612 записей.
Обнаружены дублирующиеся ключи в уникальных индексах таблицы '_ACCUMRGT25597'
Повреждены данные таблицы '_ACCUMRGT25609'. Восстановлено 282832 из 282834 записей.
Обнаружены дублирующиеся ключи в уникальных индексах таблицы '_ACCUMRGT25609'
Повреждены данные таблицы '_ACCUMRGT25623'. Восстановлено 53368 из 53418 записей.
Обнаружены дублирующиеся ключи в уникальных индексах таблицы '_ACCUMRGT25623'
Повреждены данные таблицы '_ACCRG1312'. Восстановлено 1013040 из 1013208 записей.
Повреждены данные таблицы '_ACCRGAT21337'. Восстановлено 2022170 из 2022258 записей.
Обнаружены дублирующиеся ключи в уникальных индексах таблицы '_ACCRGAT21337'
Обнаружены дублирующиеся ключи в уникальных индексах таблицы '_ACCRGED1340'

(1)Произвести ТИ ( тестирование и исправление базы данных)
еще как вариант загрузить в SQL и DBCC CHECKTABLE (_UsersWorkHistory, repair_allow_data_loss) Произвести ТИ ( тестирование и исправление базы данных)

Я же написал, что ТИ делал, оно ничего не дало.

(3)"еще как вариант загрузить в SQL и DBCC CHECKTABLE (_UsersWorkHistory, repair_allow_data_loss)" еще как вариант загрузить в SQL и DBCC CHECKTABLE (_UsersWorkHistory, repair_allow_data_loss)

(5)_UsersWorkHistory - таблица истории работы пользователя.

DBCC CHECKTABLE Производит проверку целостности всех страниц и структур, составляющих таблицу или индексированное представление.
REPAIR_ALLOW_DATA_LOSS
Пытается устранить все обнаруженные ошибки. Эти исправления могут привести к частичной потере данных.

"Если необходимо использовать аргумент REPAIR, выполните инструкцию DBCC CHECKTABLE без параметра восстановления, чтобы узнать требуемый уровень восстановления. При использовании уровня REPAIR_ALLOW_DATA_LOSS рекомендуется создать резервную копию базы данных перед выполнением инструкции DBCC CHECKTABLE с этим параметром."

Пытается устранить все обнаруженные ошибки. Эти исправления могут привести к частичной потере данных.

Частичная потеря данных может привести к более серьезным ошибкам?

Насколько я понимаю из названия таблицы, это просто история работы пользователей.
Если какой-то шаг работы пользователя сотрется - это же ни на что не влияет.
Но важно знать, что за пользователь был, возможно, у него связь с базой плохая или он оставляет базу открытой на неск.дней. Надо выявлять и вразумлять таких пользователей.
Так что мне интересна более полная информация об ошибке.

Или такая команда молча все выполнит?

(7)
Не факт что вы установите кто пользователь!

"Если необходимо использовать аргумент REPAIR, выполните инструкцию DBCC CHECKTABLE без параметра восстановления, чтобы узнать требуемый уровень восстановления. При использовании уровня REPAIR_ALLOW_DATA_LOSS рекомендуется создать резервную копию базы данных перед выполнением инструкции DBCC CHECKTABLE с этим параметром."

выполните инструкцию DBCC CHECKTABLE без параметра восстановления

Это DBCC CHECKTABLE (_UsersWorkHistory) надо писать?
я никогда не работал с SQL командами

Хотите заняться более глубоким анализом?

История работы пользователей
Таблица _UsersWorkHistory
_ID - Уникальный идентификатор пользователя информационной базы
_UserID - ID пользователя - владельца настройки
_URL - URL
_Date - Дата время
_URLHash - Хеш по URL

_ID - Уникальный идентификатор пользователя информационной базы;
_UserID - ID пользователя - владельца настройки;
_URL - URL;
_Date - Дата-время;
_URLHash - Хеш по URL;
_DataSeparationUse<n> – использование разделения данных;
_Fld<n> - общие реквизиты.

Ошибка на уникальность индексов данной таблицы возникала при попытке загрузки dt в SQL. Вылечилось загрузкой в файловую и правкой таблиц через ToolCD 1C.

Вылечилось загрузкой в файловую и правкой таблиц через ToolCD 1C

Последние скачки этого инструмента относятся к версии платформы 8.3.8. Сейчас непонятно, чем пользоваться.

На текущий момент реализованы следующие

Возможности:
- получение массива таблиц БД;
- сохранение данных таблиц в файлы ("сырые" данные!);
- загрузка данных таблиц из файлов ("сырые" данные!);
- переименование таблиц, установка им новых описаний;
- создание, удаление таблиц;
- получение массива полей таблицы, подсчёт длины одной записи;
- навигация по записям таблицы, чтение/запись полей и BLOB-полей;

- сохранение/загрузка BLOB-полей в файл;

- добавление, удаление записей;

- получение примитивной информации по метаданным;

- поддержка разных целевых платформ - Windows32/64, Linux64.

Также возможна работа с базой данных (и, также, с произвольными двоичными файлами блочной структуры) на "низком" уровне: реализованы методы по чтению/записи числовых и строковых данных из блоков файла.

Читайте также: