Контакти

Вставлення неунікального значення в унікальний індекс. Спроба вставити неунікальне значення в унікальний індекс. Що таке індекс

Вам зустрілося повідомлення, що містить рядки:
Microsoft OLE DB Provider для SQL Server: CREATE UNIQUE INDEX terminated because a duplicate key was found for index ID
або
Cannot I_nsert duplicate key row in object
або
Спроба вставити неунікальне значення в унікальний індекс.

Варіанти розв'язання:

1. У SQL Server managment studio фізично знищуємо збійний індекс (у моєму випадку це був індекс таблиці підсумків регістра бухгалтерії). У 1С розпроводимо збійні документи. У режимі тестування та виправлення ставимо галки реіндексація таблиць + перерахунок підсумків. 1С відтворює індекс без помилки. Проводимо документи, що раніше збоїли.

2. 1) За допомогою Management Studio 2005 згенерувала create-скрипт створення індексу, який глючив, і зберегла у файлик.
2) Вручну вбила косячний індекс із таблиці _AccumRgTn19455
3) Запустила запит виду
Код SQL S_elect count(*), поля_індексу
FROM AccumRgTn19455
GROUP BY поля_індексу
HAVING count(*)>1
Після того, як індекс був убитий, у мене відобразилося 15 записів, що дублюються, хоча до виконання п.2 запит нічого не повертав.
4) Переглянула всі записи та вручну почистила дублікати. Насправді я ще користувалася обробкою "Структура звіту", щоб зрозуміти, з чим взагалі маю справу. Виявилося, що у таблиці _AccumRgTn19455 зберігається регістр накопичення "Випуск продукції (податковий облік)". Я ще поколупалася sql-запитами, виявила 15 неунікальних документів і після закінчення всіх дійств перевірила в 1С, що ці документи проводяться нормально, без помилок. Просто так чистити таблиці навмання, звичайно, не варто: важливо розуміти, що чиститься і чим це може обернутися.
5) Запустила запит на створення індексу, збереженого у файлі.
6) Перевела базу в однокористувацький режим і запустила dbcc checkdb - цього разу жодної помилки не видалося.
7) Перевела базу назад в однокористувацький режим.
Все... проблема переможена. Ну ще в 1С запустила "Тестування та виправлення", там теж все пройшло нормально, перестало лаятись на неунікальний індекс.

3. Якщо неунікальність полягає у датах з нульовими значеннями, то проблема вирішується створенням бази з параметром усунення рівним 2000.

1. Якщо проблема завантаження бази даних, то:
1.1. Якщо Ви робите завантаження (використовуєте dt-файл) в базу MS SQL Server, то під час створення бази перед завантаженням вкажіть усунення дат - 2000.
Якщо база створена зі зміщенням 0, то створіть нову з 2000.

1.2. Якщо є можливість у файловому варіанті працювати з базою, виконайте Тестування та Виправлення, а також Конфігурація - Перевірка конфігурації - Перевірка логічної цілісності конфігурації + Пошук некоректних посилань.

1.3. Якщо немає файлового варіанта, спробуйте завантажити з DT в клієнт-серверний варіант із DB2 (який менш вимогливий до унікальності), а потім виконати Тестування та Виправлення, а також Конфігурація - Перевірка конфігурації - Перевірка логічної цілісності конфігурації + Пошук некоректних посилань.

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

2. Якщо проблема неунікальності проявляється під час роботи користувачів:

2.1. Знайти за допомогою методу пункту 1.4 проблемний запит.

2.1.2. Іноді помилка виникає під час виконання запитів, наприклад:

Ця помилка виникає через те, що в модулі регістру накопичення "Робочий час працівників організацій" у процедурі "ЗареєструватиПерерахунки" у запиті не стоїть службове слово "РІЗНІ".
Код 1C v 8.х. повинно бути:
Запит = Новий Запит(
"ВИБРАТИ РІЗНІ
| Основні.ФізОбличчя,
. . . . .
У останніх випущених релізах ЗУП та УПП помилка немає, т.к. там стоїть "РІЗНІ".

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

2.2.2 Приклад. Індекс у помилці називається "_Document140_VT1385_IntKeyIndNG".
Перелік полів таблиці:
_Document140_IDRRef, _KeyField, _LineNo1386, _Fld1387, _Fld1388, _Fld1389, _Fld1390, _Fld1391RRef, _Fld1392RRef, _Fld1393_LD f, _Fld1394,_Fld1395, _Fld1396RRef, _Fld1397, _Fld1398, _Fld1399RRef, _Fld22260_TYPE, _Fld22260_RTRef, _Fld22262_RR Ref, _Fld22261_RRRef
Перед виконанням наведеної нижче процедури зробіть резервну копію бази даних.
Виконайте в MS SQL Server Query Analizer:
Код SQL S_elect count(*), _Document140_IDRRef, _KeyField
від _Document140_VT1385
group by _Document140_IDRRef, _KeyField
having count(*) > 1
З його допомогою дізнайтесь значення колонок _Document140_IDRRef, _KeyField, дублюючих записів (id, key).

За допомогою запиту:
Код SQL S_elect *
від _Document140_VT1385
or _Document140_IDRRef = id2 and _KeyField = key2 or ...
подивіться на значення інших колонок записів, що дублюються.
Якщо обидва записи мають осмислені значення та ці значення різні, виправте значення _KeyField на унікальне. Для цього визначте максимальне значення _KeyField (keymax):
Код SQL S_elect max(_KeyField)
від _Document140_VT1385
where _Document140_IDRRef = id1
Замініть значення _KeyField в одному з записів, що повторюються, на правильне:
Код SQL update _Document140_VT1385
set _KeyField = keymax + 1
Тут _LineNo1386 = - додаткова умова, яка дозволяє вибрати один з двох записів, що повторюються.

Якщо одна (або обидві) з записів, що повторюються, має очевидно неправильне значення, то її потрібно видалити:
Код SQL delete from _Document140_VT1385
where _Document140_IDRRef = id1 and _LineNo1386 = lineno1
Якщо записи, що повторюються, мають однакові значення у всіх колонках, то з них потрібно залишити одну:
Код SQL S_elect distinct *
into #tmp1
від _Document140_VT1385
where _Document140_IDRRef = id1 and _KeyField = key1

Delete from _Document140_VT1385
where _Document140_IDRRef = id1 and _KeyField = key1

I_nsert into _Document140_VT1385
S_elect #tmp1

D_rop table #tmp1

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

2.2.3. Другий приклад:
Код SQL S_elect COUNT(*) AS Expr2, _IDRRef AS Expr1, _Description
FROM _Reference8_
GROUP BY _IDRRef, _Description
HAVING (COUNT(*) > 1)

2.3.4 Приклад визначення неунікальних записів за допомогою запиту 1С:Підприємство:
Код 1C v 8.х ВИБРАТИ Довідник.
З Довідник.Довідник ЯК Довідник
ЗГРУПУВАТИ ДО Довідника.Посилання
МАЮЧІ КІЛЬКІСТЬ(*) > 1

У цій статті буде описано, що робити, якщо під час роботи з 1С:Підприємство 8.1 Вам зустрілося повідомлення, що містить рядки:

Cannot insert duplicate key row in object

Спроба вставити неунікальне значення в унікальний індекс.

Що таке індекс?

Індекси є структурою, що дозволяє виконувати прискорений доступ до рядків таблиці на основі значень одного або більше її стовпців.
Індекс містить ключі, побудовані з одного або кількох стовпців таблиці або подання, та покажчики, які зіставляються з місцем зберігання заданих даних.
Індекси скорочують обсяг даних, які потрібно вважати, щоб повернути результуючий набір.

Хоча індекс і пов'язаний з конкретним стовпцем (або стовпцями) таблиці, все ж таки він є самостійним об'єктом бази даних.

Індекси таблиць у базі даних 1С:Підприємство створюються неявно при створенні об'єктів конфігурації, а також при тих чи інших налаштуваннях об'єктів конфігурації.

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

Фізично дані зберігаються на 8Кб сторінках. Відразу після створення, поки таблиця немає індексів, таблиця виглядає як купа (heap) даних. Записи немає певного порядку зберігання.
Коли ви хочете отримати доступ до даних, SQL Server буде виробляти сканування таблиці(Table scan). SQL Server сканує всю таблицю, щоб знайти шукані записи.
Звідси стають зрозумілими базові функції індексів:
- Збільшення швидкості доступу до даних,
- Підтримка унікальності даних.

Незважаючи на переваги, індекси також мають і ряд недоліків. Перший з них – індекси займають додаткове місце на дискута в оперативній пам'яті. Щоразу, коли ви створюєте індекс, ви зберігаєте ключі в порядку спадання або зростання, які можуть мати багаторівневу структуру. І чим більше/довше ключ, тим більший розмір індексу. Другий недолік – сповільнюються операціївставки, оновлення та видалення записів.
У середовищі MS SQL Server 2005 реалізовано кілька типів індексів:

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

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

Унікальність значень в стовпці, що індексується, гарантують унікальні індекси. За наявності сервер не дозволить вставити нове або змінити існуюче значення таким чином, щоб в результаті цієї операції в стовпці з'явилися два однакових значення.
Унікальний індекс є своєрідною надбудовою і може бути реалізований як кластерного, так і для некластерного індексу. В одній таблиці може існувати один унікальний кластерний та безліч унікальних некластерних індексів.
Унікальні індекси слід визначати лише тоді, коли це дійсно необхідно. Для забезпечення цілісності даних у стовпці можна визначити обмеження цілісності UNIQUE або PRIMARY KEY, а не вдаватися до унікальних індексів. Їх використання лише задля забезпечення цілісності даних є невиправданою витрачанням простору в базі даних. Крім того, на їх підтримку витрачається процесорний час.

1С:Підприємство 8.1, починаючи з версії 8.1, активно використовує кластерні унікальні індекси. Це означає, що при конвертації з 8.0 або переході з 8.1.7 можна отримати помилку неунікального індексу.

Якщо неунікальність полягає в датах з нульовими значеннями, проблема вирішується створенням бази з параметром зміщення рівним 2000.

Що робити?

1. Якщо проблема завантаження бази даних, то:

1.1. Якщо Ви робите завантаження (використовуєте dt-файл) в базу MS SQL Server, то під час створення бази перед завантаженням вкажіть зміщення дат - 2000.

Якщо база створена зі зміщенням 0, то створіть нову з 2000.

1.2. Якщо у файловому варіанті є можливість працювати з базою, виконайте Тестування та Виправлення, а також Конфігурація — Перевірка конфігурації — Перевірка логічної цілісності конфігурації + Пошук некоректних посилань.

1.3. Якщо немає файлового варіанта, спробуйте завантажити з DT у клієнт-серверний варіант з DB2 (який менш вимогливий до унікальності), а потім виконати Тестування та Виправлення, а також Конфігурація — Перевірка конфігурації — Перевірка логічної цілісності конфігурації + Пошук некоректних посилань.

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

2.2.2 Приклад. Індекс у помилці називається "_Document140_VT1385_IntKeyIndNG".

Перелік полів таблиці:

Document140_IDRRef, _KeyField, _LineNo1386, _Fld1387, _Fld1388, _Fld1389, _Fld1390, _Fld1391RRef, _Fld1392RRef, _Fld1393_TYPE, _F Fld1394,

Fld1395, _Fld1396RRef, _Fld1397, _Fld1398, _Fld1399RRef, _Fld22260_TYPE, _Fld22260_RTRef, _Fld22260_RRRef, _Fld2222_ 1_RRRef

Перед виконанням наведеної нижче процедури зробіть резервну копію бази даних.
Виконайте в MS SQL Server Query Analizer:

select count(*), _Document140_IDRRef, _KeyField
від _Document140_VT1385
group by _Document140_IDRRef, _KeyField
having count(*) > 1

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

За допомогою запиту:

select *
від _Document140_VT1385
or _Document140_IDRRef = id2 and _KeyField = key2 or …

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

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

select max(_KeyField)
від _Document140_VT1385
where _Document140_IDRRef = id1

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

update _Document140_VT1385
set _KeyField = keymax + 1

Тут _LineNo1386 = — додаткова умова, яка дозволяє вибрати один із двох записів, що повторюються.

Якщо одна (або обидві) з записів, що повторюються, має очевидно неправильне значення, то її потрібно видалити:


where _Document140_IDRRef = id1 and _LineNo1386 = lineno1

Якщо записи, що повторюються, мають однакові значення у всіх колонках, то з них потрібно залишити одну:

select distinct *
into #tmp1
від _Document140_VT1385
where _Document140_IDRRef = id1 and _KeyField = key1

delete from _Document140_VT1385
where _Document140_IDRRef = id1 and _KeyField = key1

insert into _Document140_VT1385
select #tmp1

drop table #tmp1

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

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

2.3.5 Зробити індекс субд не є унікальним. Закриптувати індекс за допомогою Management Studio.

2.3.6 Випадок при обміні в РБД. Помилка посідає «допоміжні» таблиці, пов'язані з розрахунком підсумків чи аналітики. Наприклад:

Помилка виклику методу контексту (Записати): Спроба вставки неунікального значення в унікальний індекс:
Microsoft OLE DB Provider для SQL Server: Використовувати необов'язковий duplicate key row in object 'dbo._AccntRegED10319' with unique index '_Accnt10319_ByPeriod_TRNRN'.
HRESULT=80040E2F, SQLSrvr: Error state=1, Severity=E, native=2601, line=1

У цьому випадку перед завантаженням вимкнути використання підсумків, завантажити повідомлення, увімкнути використання підсумків та перерахувати.

Вам зустрілося повідомлення, що містить рядки:
Microsoft OLE DB Provider для SQL Server: CREATE UNIQUE INDEX terminated because a duplicate key was found for index ID
або
Cannot I_nsert duplicate key row in object
або
Спроба вставити неунікальне значення в унікальний індекс.

Варіанти розв'язання:

1. У SQL Server managment studio фізично знищуємо збійний індекс (у моєму випадку це був індекс таблиці підсумків регістра бухгалтерії). У 1С розпроводимо збійні документи. У режимі тестування та виправлення ставимо галки реіндексація таблиць + перерахунок підсумків. 1С відтворює індекс без помилки. Проводимо документи, що раніше збоїли.

2. 1) За допомогою Management Studio 2005 згенерувала create-скрипт створення індексу, який глючив, і зберегла у файлик.
2) Вручну вбила косячний індекс із таблиці _AccumRgTn19455
3) Запустила запит виду
Код SQL S_elect count(*), поля_індексу
FROM AccumRgTn19455
GROUP BY поля_індексу
HAVING count(*)>1
Після того, як індекс був убитий, у мене відобразилося 15 записів, що дублюються, хоча до виконання п.2 запит нічого не повертав.
4) Переглянула всі записи та вручну почистила дублікати. Насправді я ще користувалася обробкою "Структура звіту", щоб зрозуміти, з чим взагалі маю справу. Виявилося, що у таблиці _AccumRgTn19455 зберігається регістр накопичення "Випуск продукції (податковий облік)". Я ще поколупалася sql-запитами, виявила 15 неунікальних документів і після закінчення всіх дійств перевірила в 1С, що ці документи проводяться нормально, без помилок. Просто так чистити таблиці навмання, звичайно, не варто: важливо розуміти, що чиститься і чим це може обернутися.
5) Запустила запит на створення індексу, збереженого у файлі.
6) Перевела базу в однокористувацький режим і запустила dbcc checkdb - цього разу жодної помилки не видалося.
7) Перевела базу назад в однокористувацький режим.
Все... проблема переможена. Ну ще в 1С запустила "Тестування та виправлення", там теж все пройшло нормально, перестало лаятись на неунікальний індекс.

3. Якщо неунікальність полягає у датах з нульовими значеннями, то проблема вирішується створенням бази з параметром усунення рівним 2000.

1. Якщо проблема завантаження бази даних, то:
1.1. Якщо Ви робите завантаження (використовуєте dt-файл) в базу MS SQL Server, то під час створення бази перед завантаженням вкажіть усунення дат - 2000.
Якщо база створена зі зміщенням 0, то створіть нову з 2000.

1.2. Якщо є можливість у файловому варіанті працювати з базою, виконайте Тестування та Виправлення, а також Конфігурація - Перевірка конфігурації - Перевірка логічної цілісності конфігурації + Пошук некоректних посилань.

1.3. Якщо немає файлового варіанта, спробуйте завантажити з DT в клієнт-серверний варіант із DB2 (який менш вимогливий до унікальності), а потім виконати Тестування та Виправлення, а також Конфігурація - Перевірка конфігурації - Перевірка логічної цілісності конфігурації + Пошук некоректних посилань.

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

2. Якщо проблема неунікальності проявляється під час роботи користувачів:

2.1. Знайти за допомогою методу пункту 1.4 проблемний запит.

2.1.2. Іноді помилка виникає під час виконання запитів, наприклад:

Ця помилка виникає через те, що в модулі регістру накопичення "Робочий час працівників організацій" у процедурі "ЗареєструватиПерерахунки" у запиті не стоїть службове слово "РІЗНІ".
Код 1C v 8.х. повинно бути:
Запит = Новий Запит(
"ВИБРАТИ РІЗНІ
| Основні.ФізОбличчя,
. . . . .
У останніх випущених релізах ЗУП та УПП помилка немає, т.к. там стоїть "РІЗНІ".

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

2.2.2 Приклад. Індекс у помилці називається "_Document140_VT1385_IntKeyIndNG".
Перелік полів таблиці:
_Document140_IDRRef, _KeyField, _LineNo1386, _Fld1387, _Fld1388, _Fld1389, _Fld1390, _Fld1391RRef, _Fld1392RRef, _Fld1393_LD f, _Fld1394,_Fld1395, _Fld1396RRef, _Fld1397, _Fld1398, _Fld1399RRef, _Fld22260_TYPE, _Fld22260_RTRef, _Fld22262_RR Ref, _Fld22261_RRRef
Перед виконанням наведеної нижче процедури зробіть резервну копію бази даних.
Виконайте в MS SQL Server Query Analizer:
Код SQL S_elect count(*), _Document140_IDRRef, _KeyField
від _Document140_VT1385
group by _Document140_IDRRef, _KeyField
having count(*) > 1
З його допомогою дізнайтесь значення колонок _Document140_IDRRef, _KeyField, дублюючих записів (id, key).

За допомогою запиту:
Код SQL S_elect *
від _Document140_VT1385
or _Document140_IDRRef = id2 and _KeyField = key2 or ...
подивіться на значення інших колонок записів, що дублюються.
Якщо обидва записи мають осмислені значення та ці значення різні, виправте значення _KeyField на унікальне. Для цього визначте максимальне значення _KeyField (keymax):
Код SQL S_elect max(_KeyField)
від _Document140_VT1385
where _Document140_IDRRef = id1
Замініть значення _KeyField в одному з записів, що повторюються, на правильне:
Код SQL update _Document140_VT1385
set _KeyField = keymax + 1
Тут _LineNo1386 = - додаткова умова, яка дозволяє вибрати один з двох записів, що повторюються.

Якщо одна (або обидві) з записів, що повторюються, має очевидно неправильне значення, то її потрібно видалити:
Код SQL delete from _Document140_VT1385
where _Document140_IDRRef = id1 and _LineNo1386 = lineno1
Якщо записи, що повторюються, мають однакові значення у всіх колонках, то з них потрібно залишити одну:
Код SQL S_elect distinct *
into #tmp1
від _Document140_VT1385
where _Document140_IDRRef = id1 and _KeyField = key1

Delete from _Document140_VT1385
where _Document140_IDRRef = id1 and _KeyField = key1

I_nsert into _Document140_VT1385
S_elect #tmp1

D_rop table #tmp1

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

2.2.3. Другий приклад:
Код SQL S_elect COUNT(*) AS Expr2, _IDRRef AS Expr1, _Description
FROM _Reference8_
GROUP BY _IDRRef, _Description
HAVING (COUNT(*) > 1)

2.3.4 Приклад визначення неунікальних записів за допомогою запиту 1С:Підприємство:
Код 1C v 8.х ВИБРАТИ Довідник.
З Довідник.Довідник ЯК Довідник
ЗГРУПУВАТИ ДО Довідника.Посилання
МАЮЧІ КІЛЬКІСТЬ(*) > 1

Вам зустрілося повідомлення, яке містить рядки:
Microsoft OLE DB Provider для SQL Server: CREATE UNIQUE INDEX terminated because a duplicate key was found for index ID
або
Cannot I_nsert duplicate key row in object
або
Спроба вставити неунікальне значення в унікальний індекс.

Варіанти розв'язання:

1. У SQL Server managment studio фізично знищуємо збійний індекс (у моєму випадку це був індекс таблиці підсумків регістра бухгалтерії). У 1С розпроводимо збійні документи. У режимі тестування та виправлення ставимо галки реіндексація таблиць + перерахунок підсумків. 1С відтворює індекс без помилки. Проводимо документи, що раніше збоїли.

2. 1) За допомогою Management Studio 2005 згенерувала create-скрипт створення індексу, який глючив, і зберегла у файлик.
2) Вручну вбила косячний індекс із таблиці _AccumRgTn19455
3) Запустила запит виду
Код SQL S_elect count(*), поля_індексу
FR OM AccumRgTn19455
GROUP BY поля_індексу
HAVING count(*)>1
Після того, як індекс був убитий, у мене відобразилося 15 записів, що дублюються, хоча до виконання п.2 запит нічого не повертав.
4) Переглянула всі записи та вручну почистила дублікати. Насправді я ще користувалася обробкою "Структура звіту", щоб зрозуміти, з чим взагалі маю справу. Виявилося, що у таблиці _AccumRgTn19455 зберігається регістр накопичення "Випуск продукції (податковий облік)". Я ще поколупалася sql-запитами, виявила 15 неунікальних документів і після закінчення всіх дійств перевірила в 1С, що ці документи проводяться нормально, без помилок. Просто так чистити таблиці навмання, звичайно, не варто: важливо розуміти, що чиститься і чим це може обернутися.
5) Запустила запит на створення індексу, збереженого у файлі.
6) Перевела базу в однокористувацький режим і запустила dbcc checkdb - цього разу жодної помилки не видалося.
7) Перевела базу назад в однокористувацький режим.
Все... проблема переможена. Ну ще в 1С запустила "Тестування та виправлення", там теж все пройшло нормально, перестало лаятись на неунікальний індекс.

3. Якщо неунікальність полягає у датах з нульовими значеннями, то проблема вирішується створенням бази з параметром усунення рівним 2000.

1. Якщо проблема завантаження бази даних, то:
1.1. Якщо Ви робите завантаження (використовуєте dt-файл) в базу MS SQL Server, то під час створення бази перед завантаженням вкажіть усунення дат - 2000.
Якщо база створена зі зміщенням 0, то створіть нову з 2000.

1.2. Якщо є можливість у файловому варіанті працювати з базою, виконайте Тестування та Виправлення, а також Конфігурація - Перевірка конфігурації - Перевірка логічної цілісності конфігурації + Пошук некоректних посилань.

1.3. Якщо немає файлового варіанта, спробуйте завантажити з DT в клієнт-серверний варіант із DB2 (який менш вимогливий до унікальності), а потім виконати Тестування та Виправлення, а також Конфігурація - Перевірка конфігурації - Перевірка логічної цілісності конфігурації + Пошук некоректних посилань.

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

2. Якщо проблема неунікальності проявляється під час роботи користувачів:

2.1. Знайти за допомогою методу пункту 1.4 проблемний запит.

2.1.2. Іноді помилка виникає під час виконання запитів, наприклад:

Ця помилка виникає через те, що в модулі регістру накопичення "Робочий час працівників організацій" у процедурі "ЗареєструватиПерерахунки" у запиті не стоїть службове слово "РІЗНІ".
Код 1C v 8.х. повинно бути:
Запит = Новий Запит(
"ВИБРАТИ РІЗНІ
| Основні.ФізОбличчя,
. . . . .
У останніх випущених релізах ЗУП та УПП помилка немає, т.к. там стоїть "РІЗНІ".

2.2. Після знаходження проблемного індексу з попереднього пункту необхідно знайти неунікальний запис.
2.2.1. "Риба" скрипта для визначення неунікальних записів за допомогою SQL:
Код SQL S_elect COUNT(*) Counter,<перечисление всех полей соответствующего индекса>fr om<имя таблицы>
GROUP BY<перечисление всех полей соответствующего индекса>
HAVING Counter > 1

2.2.2 Приклад. Індекс у помилці називається "_Document140_VT1385_IntKeyIndNG".
Перелік полів таблиці:
_Document140_IDRRef, _KeyField, _LineNo1386, _Fld1387, _Fld1388, _Fld1389, _Fld1390, _Fld1391RRef, _Fld1392RRef, _Fld1393_LD f, _Fld1394,_Fld1395, _Fld1396RRef, _Fld1397, _Fld1398, _Fld1399RRef, _Fld22260_TYPE, _Fld22260_RTRef, _Fld22262_RR Ref, _Fld22261_RRRef
Перед виконанням наведеної нижче процедури зробіть резервну копію бази даних.
Виконайте в MS SQL Server Query Analizer:
Код SQL S_elect count(*), _Document140_IDRRef, _KeyField
fr om _Document140_VT1385
group by _Document140_IDRRef, _KeyField
having count(*) > 1
З його допомогою дізнайтесь значення колонок _Document140_IDRRef, _KeyField, дублюючих записів (id, key).

За допомогою запиту:
Код SQL S_elect *
fr om _Document140_VT1385
where _Document140_IDRRef = id1 and _KeyField = key1 or _Document140_IDRRef = id2 and _KeyField = key2 or ...
подивіться на значення інших колонок записів, що дублюються.
Якщо обидва записи мають осмислені значення та ці значення різні, виправте значення _KeyField на унікальне. Для цього визначте максимальне значення _KeyField (keymax):
Код SQL S_elect max(_KeyField)
fr om _Document140_VT1385
wh ere _Document140_IDRRef = id1
Замініть значення _KeyField в одному з записів, що повторюються, на правильне:
Код SQL upd ate _Document140_VT1385
set _KeyField = keymax + 1

Тут _LineNo1386 = - додаткова умова, яка дозволяє вибрати один з двох записів, що повторюються.

Якщо одна (або обидві) з записів, що повторюються, має очевидно неправильне значення, то її потрібно видалити:
Код SQL delete from _Document140_VT1385
wh ere _Document140_IDRRef = id1 and _LineNo1386 = lineno1
Якщо записи, що повторюються, мають однакові значення у всіх колонках, то з них потрібно залишити одну:
Код SQL S_elect distinct *
into #tmp1
від _Document140_VT1385

Delete from _Document140_VT1385
wh ere _Document140_IDRRef = id1 and _KeyField = key1

I_nsert into _Document140_VT1385
S_elect #tmp1

D_rop table #tmp1

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

2.2.3. Другий приклад:
Код SQL S_elect COUNT(*) AS Expr2, _IDRRef AS Expr1, _Description
FROM _Reference8_
GROUP BY _IDRRef, _Description
HAVING (COUNT(*) > 1)

2.3.4 Приклад визначення неунікальних записів за допомогою запиту 1С:Підприємство:
Код 1C v 8.х ВИБРАТИ Довідник.
З Довідник.Довідник ЯК Довідник
ЗГРУПУВАТИ ДО Довідника.Посилання
МАЮЧІ КІЛЬКІСТЬ(*) > 1

Інформація взята із сайту

Помилка виникає, якщо в базі є якісь об'єкти, реквізити, субконто - значення NULL, а у них такого значення бути не може. І з'являється така помилка лише у SQL базах. Тобто. якщо таку базу вивантажити у файлову, там вже цієї помилки нічого очікувати. Т.к. у файлової бази свої таблиці (всього 4 шт.), А у SQL свої. І SQL база критично реагує такі значення у таблицях.

Ця проблема не вирішується ніякими тестуваннями (ні зовнішнім, ні внутрішнім) у жодних варіантах баз (SQL або файлова) і навіть Процедурою _1sp_DBReindex в менеджері SQL, яка начебто повинна проводити реструктуризацію таблиць у SQL.

Розберемо вирішення проблеми з прикладу переходу з Бухгалтерії 3.0 ПРОФ на КОРП. Після переходу у рахунку 68.01 з'являється нове субконто Реєстрація В Податковому Органі. І тоді, в базах на SQL, все створення в ПРОФ версії документи, які використовують цей рахунок, не будуть перекладатися. Виходитиме вище показана помилка. Т.к. це нове субконто у старих документів, у проводках, запишеться зі значенням NULL (хоча має бути Порожнє значення, чи податковий орган).

Щоб усунути цю помилку, потрібно забрати значення NULL там, де їх не повинно бути. У разі у документах, де використовується субконто Реєстрація В Податковому Органі. Зробити це можна, написавши обробку, яка замінить NULL на пусте значення (готову обробку можна завантажити з цієї статті). Робити обробкою, т.к. спроба змінити значення цього субконто в проводках документа вручну, призводить до тієї ж помилки.

Обробку для заміни NULL"ів у всіх субконтах РеєстраціяВПодатковомуОргані можна завантажити з цієї статті, внизу.

А так замінити NULL в SQL базі не вийде, під час виконання обробки буде видана та сама помилка. Тому необхідно зробити так:

1. Вивантажити вже робочу, переведену на КОРП версію, SQL базу в dt'шник (у конфігураторі Адміністрування – Вивантажити базу – виберіть куди вивантажити базу у вигляді файлу *.dt)

2. Завантажити dt'шник у файлову базу (у непотрібній або заздалегідь підготовленій, чистій, файловій базі, у конфігураторі Адміністрація – Завантажити базу – вибрати раніше вивантажений dt'шник)

3. Виконати обробку у файловій базі (там помилки не буде і всі NULL'и коректно замінюватимуться) (як виконати обробку описано нижче)

5. Тепер навпаки вивантажити dt'шник із файлової бази та завантажити його в SQL базу. Тепер при проведенні опрацьованих документів помилки не виходитиме.

Обробка з цієї статті знаходить усі документи, за зазначений період, у яких у проводках фігурує субконтна Реєстрація В Податковому Органі (яка з'являється в КОРП версії), у якого значення NULL. І замінює це значення на Пусте значення.

У обробці необхідно вказати період, протягом якого необхідно обробити документи (можна протягом усього період у якому ведеться облік у основі) і натиснути «Заповнити табличну часть». Після чого можна галками позначити якісь документи обробити (можна вибрати все) і натиснути кнопку «Виконати обробку».

Відповідно якщо у когось така ж помилка, але НЕ після переходу на КОРП, а наприклад після обміну, завантаження якихось даних, виконання якихось обробок тощо. Це необхідно виявити, де привласнилося значення NULL у конкретному документі/довіднику та подібним способом прибрати цей NULL але вже своєю обробкою, але в тому порядку, як описано вище. Пам'ятайте, що NULL може бути як у проводках документа, в т.ч. не тільки бухгалтерських, так і десь на формі документа/довідника, в якомусь реквізиті, але в такому разі він, напевно, навіть не відкриється.

Також якщо ця помилка з'явилася у вас при проведенні документа, після того як ви переклали файлову базу Бух КОРП на SQL (а база колись спочатку була ПРОФ), то значить у тих документів, що були створені в ПРОФ версії, зараз також в субконто. Значення NULL і SQL база таке не приймає. І при завантаженні бази в SQL виходитиме така помилка. Тут насправді у файловій базі значень NULL за фактом нічого очікувати, але SQL у таблиці завантажить саме такі значення. Тому тут треба змусити базу SQL створити ці NULL і потім у файловій базі їх виправити. Але як це зробити, вже не підкажу.



Сподобалася стаття? Поділіться їй