gifts2017

Ошибка "Violation of PRIMARY KEY constraint ... Cannot insert duplicate key in object"

Опубликовал Xer shi (Xershi) в раздел Администрирование - Системное

При работе в 1С на SQL может появиться ошибка "Violation of PRIMARY KEY constraint ... Cannot insert duplicate key in object".
Сегодня попытаемся понять, почему она возникла и как ее устранить!

Предыстория:

Никого не удивлю, типичный случай. Приходит бухгалтер и сообщает, что хотела провести документ в 1С 7.7, но он выпадает в ошибку.

Начал разбираться, прошелся отладчиком в копии по коду. Причину сразу не нашел, до конца кода отладку не провел и решил нажать F5, чтобы продолжить работу в базе. Документ провелся. Но я решил отменить проведение и повторно провести его. И вот тут вылетела ошибка "Violation of PRIMARY KEY constraint 'PK_RA17286'. Cannot insert duplicate key in object 'RA17286'." Естественно, это только частный случай, как эта ошибка может возникнуть, но ее решение подойдет для каждого!

 

Решение:

Данная ошибка в моем случае связана с тем, что в SQL есть движение документа, но документ не проведен. В момент его проведения должна создаться запись в регистре, но она уже есть!

Я нашел два решения:

1. Простой, но долгий.

2. Сложный, но быстрый. 

Решение 1.

Зайти в конфигуратор и нажать ТиИ (Тестирование и исправление ИБ). В моем случае база весит ~ 16 гигабайт. ТиИ работало на тестовом сервере ~ 24 часа. Думаю, время решение такой ошибки не устроит вас! Но если у вас есть время или нет в штате опытного программиста, то можете выбрать этот вариант решения вопроса!

Решение 2.

У нас 1С 7.7 стоит на MS SQL Server 2000. Копия базы также развернута на SQL. 

Итак, что нам понадобится:

1. Файл "1Cv7.DDS", который лежит в каталоге базы 1с 7.7.

2. Имя документа из конфигуратора.

3. Доступ в SQL.

Откроем файл "1Cv7.DDS" (я использую просмотр по F3 в тоталкомандере). Найдем строку с именем документа. Вы увидите таблицу и в колонке "Name" или "SQLTableNam" будет написано название таблицы в SQL (в моем случае это было "DH17245"). Заходим в "Enterprise Manager" нашего SQL. Находим нашу базу и ищем в ней таблицу с нужным названием (я искал "DH17245"). Когда нашли таблицу с таким именем, то кликаем по таблице ПКМ "Открыть таблицу" (Open table) -> "Вернуть все строки" (Return all rows). Там ищем запись по вашему документу. Мне удалось его легко найти, документ был один в нужном периоде. Нашли запись и запомнили его IDDOC (у меня было "KLMN"). Теперь ищем таблицу, которая вывалилась в ошибке (у меня "RA17286"). Аналогично открываем таблицу с ошибкой (моя таблица "RA17286") и находим запись на нужный документ (мой документ "KLMN"). Удалим запись ПКМ по строке нажать Delete -> Yes. 

Все, теперь ошибка при проведении возникать перестанет!

 

Итог:

Важно! Я четко знал, какой документ был сбойный. У меня была копия базы для экспериментов! Повторять только на копии!

См. также

Подписаться Добавить вознаграждение
Комментарии
1. Сергей (Che) Коцюра (CheBurator) 19.08.15 01:17
Не описано действительно нужное - 1. причина почему такая ошибка появилась 2. как избежать появления такой ошибки.
alyaev.a.v; +1 Ответить 1
2. Александр Аляев (alyaev.a.v) 19.08.15 09:26
Даже если сбойный док 1, то вариант так себе. Потом бух найдет еще один, потом еще и понеслась...
ТИИ избавляет сразу от ВСЕХ таких кривых доков/записей.
Да и не безопасно все это.
3. Xer shi (Xershi) 19.08.15 09:30
(1) CheBurator, моя причина описана в предыстории. Ваша может быть совсем другой!
(2) alyaev.a.v, я привел 2 варианта! Можете предложить третий? Не забываем читать ИТОГ!
4. Александр Аляев (alyaev.a.v) 19.08.15 09:34
(3) Xershi, Ок, знали док это хорошо, сейчас есть уверенность что таких кривых доков больше нет?
5. Xer shi (Xershi) 19.08.15 09:34
(4) alyaev.a.v, конечно! Код отлажен, ТиИ сделано!
6. Александр Аляев (alyaev.a.v) 19.08.15 09:38
(5) Xershi, Если ТИИ сделано, тогда вообще не пойму зачем вариант 2 ???
Вариант 2 никакого отношения к проблеме не имеет получается, описание как найти по структуре базы таблицу в скуле и удалить запись.
7. Xer shi (Xershi) 19.08.15 09:42
(6) alyaev.a.v, потому что у меня 2 копии базы. На одной запустил ТиИ. На второй сделал удаление.
А на рабочей базе повторил второй вариант. Согласись запустить ТиИ на рабочей базе на 24 часа не вариант!
8. Петр Вел (shmellevich) 19.08.15 09:51
(1)
1. причина - нагрузка на SQL базу при большом количестве пользователей, особенно когда они работают с одним видом документов, и главная причина платформа 1С 7.7 и архитектура хранения документов в базе данных.

2. как избежать появления такой ошибки. - по своему опыту скажу подобные ошибки возникают настолько редко, что их даже воспроизвести не получится, у меня из 13 баз идентичных такие ошибки встречались за 3 года всего 2 или 3 раза, при этом размеры баз 10-ки ГБ.

Автору спасибо за инструкцию, для тех у кого это может проявиться.
9. Александр Аляев (alyaev.a.v) 19.08.15 09:57
(7) Xershi, Не соглашусь.
Как временный вариант, чтобы дотянуть до выходных и сделать ТИИ подходит.
Но оставить так базу...Я бы сделал ТИИ и не парился бы.

Ну как говорится это решает специалист, повторюсь если есть уверенность что больше нет косяков, то почему и нет.
10. Сергей (Che) Коцюра (CheBurator) 19.08.15 14:34
(3) "Данная ошибка в моем случае связана с тем, что в SQL есть движение документа, но документ не проведен"
- это не ошибка. Это следствие ошибки. Штатными вариантами действий добиться такой ситуации - навскидку не представляю.
11. Сергей (Che) Коцюра (CheBurator) 19.08.15 14:36
(8) спсб за поснения. Но причина - так и осталась невыясненной... ;-)
12. Xer shi (Xershi) 19.08.15 14:48
(11) CheBurator, еще раз повторяю как получить такую ошибку: в моем случае в документе была ошибка и документ не проводился. Я решил пройти отладчиком, шел через ф8. До конца кода не дошел и нажал ф5. Документ провелся без ошибки! Но не должен был проводиться, а выйти в ошибку. Но он провелся, конечно не корректно. И после отмены проведения и повторного проведения возникает ошибка. Я думаю это баг платформы.
13. Сергей (Che) Коцюра (CheBurator) 19.08.15 16:04
(12) фигня какая-то...
> Документ провелся без ошибки! Но не должен был проводиться, а выйти в ошибку. Но он провелся, конечно не корректно.
- тем не менее провелся. штатно. с записью движений в регистр. ПРОБЛЕМ НЕ ВИЖУ.

> И после отмены проведения и повторного проведения возникает ошибка.
- отмену проведения штатно делали? повторное проведение выполнилось нормально (провелось с записью движений)? или не провелось с выдачей штатного сообщения? Дополнительным кодом с использованием транзакций - игрались?
.
Такая ошибка воспроизводится устойчиво? если да - просьба записать коротенькое видео.
14. Xer shi (Xershi) 19.08.15 16:16
(13) CheBurator, вы статью прочитайте!!!
И код уже исправлен, поэтому записывать даже нечего.
15. Дмитрий Дрейцер (MadDAD) 19.08.15 16:21
(12) может в табло в отладчике было что-то хитрое?

Вообще вот нашел методику - http://www.klerk.ru/print/1996 по аналогии можно и с регистрами.
16. Xer shi (Xershi) 19.08.15 16:30
(15) MadDAD, ничего хитрого не было, вы же уже читали первоисточник http://forum.infostart.ru/forum9/topic136472/. Ссылка ваша хорошая, только сложно это переварить, если не работать со скулем.
17. Сергей (Che) Коцюра (CheBurator) 19.08.15 16:51
(14) а что такого ХИТРОГО было в коде, что приводило к появлению ошибки?
то что документ провелся (хотя по вашему замыслу не должен был проводиться) - это штатное поведение.
то что документ отменили проведение - это штатная возможность
то что потом документ повторно провели (успешно или неуспешно) - это штатная возможность.
здесь ничего косячить не должно.

а вот то, что поправили код и внезапно у непроведенного документа не стало движений как и должно быть (а раньше были) - вот это и напрягает...
может вы там хитро с транзакциями баловались.. или прямые запросы юзаете...
18. Xer shi (Xershi) 19.08.15 17:20
(17) CheBurator, вот именно
то что потом документ повторно провели (успешно или неуспешно) - это штатная возможность.
Он выпал в ошибку. Решение указал выше.
Прочтите (16).
Без удаления записи в скуле документ при проведении вывалился с ошибкой на скуле.
С удалением записи в скуле документ при проведении вылетает на ошибке кода в 1с.
После удаления и правки кода документ провелся нормально.
19. Василий Коровин (vasyak319) 19.08.15 17:49
Вы удаляете движение из таблицы регистра. А что у вас при этом с итогами?
20. Сергей (Che) Коцюра (CheBurator) 19.08.15 19:40
(18) он выпал в ошибку (скуль отрапортовал и это вообщем неинтересно) потому что до этого была ошибочная ситуация: документ не проведен, но движения присутствуют - а вот это интересно как именно этого добились.... и какой именно код (исходный, приводящий устойчиво к скульной ошибке ) поменяли, что теперь цепочка операций "проведение-распроведение-повторное проведение" отрабатывает нормально как и должно?

ответа на вопросы чуть выше вообщем так и не было: - игрались с транзакциями при проведении/распроведении доков? прямые запросы использовали в проведении/распроведении? использовали отмену проведения путем модификации прямыми запросами признака проведения документа? до возникновения ошибочной ситуации - про которую написал скуль - модифицировали что либо в таблицах регистров прямыми запросами или непосредственно в самом скуле?
21. Xer shi (Xershi) 20.08.15 08:47
(20) CheBurator, если бы вы прочли все внимательно, то вопрос бы не возник. По коду как я понял: делалась проводка, но в счете дебета использовался старый план счетов(до 2012,а сейчас используем новый), из-за этого он не подставлялся в проводку. В этом была ошибка кода, после правки счет берется из нового плана счетов. Когда удалил запись, то и проблемы не стало!
22. Сергей (Che) Коцюра (CheBurator) 20.08.15 18:05
А при чем здесь ПРОВОДКИ и наличие движений ПО РЕГИСТРУ у непроведенного документа...?
23. Xer shi (Xershi) 21.08.15 08:53
(22) CheBurator, для этого написана статья.
24. Андрей М (_Z1) 21.08.15 11:30
(8) Это не причина.
sql держит любую нагрузку.
Как бы принцип транзакции или все сделано или все откатили.

Поддержу Cheburator прав на все 100%