При обновлении конфигурации «1С:Бухгалтерия предприятия 3.0» на новые релизы (начиная с 3.0.65 и выше) многие технические специалисты сталкиваются с критической остановкой процесса. Проблема обычно проявляется после успешного применения изменений в Конфигураторе, на этапе запуска в режиме «Предприятие». Система выдает ошибку вида Ошибка SDBL: Таблица или поле ID не содержится в разделе FROM или сообщает о нарушении ограничений PRIMARY KEY в служебной таблице _tmpRCT при попытке выполнить тестирование и исправление (ТИИ).
В этой статье мы подробно разберем причины возникновения данной ситуации, проанализируем внутренние механизмы платформы и рассмотрим несколько эффективных способов решения проблемы — от «быстрых» правок кода до глубокой очистки базы данных.
Проанализируем ситуацию: корень проблемы кроется в изменении режима совместимости платформы (обычно при переходе с 8.3.10 на 8.3.12 или выше). В новых версиях платформы 1С:Предприятие 8.3.12+ были существенно переработаны механизмы работы с планами обмена и расширениями конфигурации. Выясним причину: при реструктуризации базы данных система пытается перестроить индексы и внутренние идентификаторы таблиц. Если в базе присутствуют «мусорные» метаданные или старые планы обмена с префиксом Удалить, механизм реструктуризации может дать сбой, назначив двум разным объектам одинаковые внутренние постфиксы (идентификаторы).
Официальная поддержка 1С подтверждает (ошибка №000048134), что в поврежденных базах могут существовать, например, две таблицы Const24 и Node24 с одинаковым числовым окончанием. Это приводит к тому, что временная таблица _tmpRCT, создаваемая во время ТИИ для пересчета ссылок, получает дублирующиеся записи, что и вызывает ошибку PRIMARY KEY.
Если обновление «падает» на этапе работы обработчиков обновления в режиме «Предприятие» при вызове метода Записать() для идентификаторов объектов метаданных, мы можем временно модифицировать код, чтобы позволить системе завершить процесс. Рассмотрим пример исправления в общем модуле СтандартныеПодсистемыСервер.
Ошибка часто возникает в процедуре ЗарегистрироватьОбъектНаВсехУзлах, когда параметр ИмяПланаОбмена принимает значение "Полный". В поврежденной базе метод ЭтотУзел() для этого плана обмена может возвращать Неопределено, что является некорректным поведением платформы.
Разберем по шагам, что нужно сделать:
СтандартныеПодсистемыСервер процедуру ЗарегистрироватьОбъектНаВсехУзлах.
Процедура ЗарегистрироватьОбъектНаВсехУзлах(Знач Объект, Знач ИмяПланаОбмена, Знач ВключаяГлавныйУзел = Истина) Экспорт
// Добавляем проверку, чтобы избежать падения при некорректном состоянии плана обмена
Если ПланыОбмена[ИмяПланаОбмена].ЭтотУзел() = Неопределено Тогда
Возврат;
КонецЕсли;
// Далее идет типовой код...
ТекстЗапроса = "ВЫБРАТЬ ПланОбмена.Ссылка КАК Получатель ИЗ ПланОбмена." + ИмяПланаОбмена + " КАК ПланОбмена...";
// ...
КонецПроцедуры
Важно: Этот метод является обходным путем («костылем»), который позволяет дойти до конца обновления, но не лечит саму структуру таблиц в SQL. После применения этого способа база все еще может выдавать ошибки при попытке ТИИ.
Проанализируем ситуацию в Конфигураторе. Часто виновником конфликта идентификаторов становятся старые планы обмена, которые были помечены на удаление разработчиками 1С, но физически остались в структуре базы. Выяснено, что удаление некоторых из них помогает платформе успешно провести реструктуризацию.
Посмотрим, как это сделать правильно:
ПланОбмена, имеющие префикс Удалить... или УдалитьОбмен....ПланОбмена.УдалитьОбменРозницаБухгалтерия20. В ряде случаев именно его удаление из дерева метаданных перед обновлением режима совместимости полностью устраняло ошибку SDBL.Этот метод заставляет платформу пересчитать DBSchema (внутреннюю схему базы) и устранить дублирование идентификаторов таблиц.
Если ТИИ продолжает выдавать ошибку PRIMARY KEY в _tmpRCT, это означает, что логическая целостность системных таблиц SQL нарушена окончательно. В таком случае самым надежным и профессиональным решением будет перенос всех данных в пустую базу с идентичной конфигурацией. Рассмотрим этот процесс подробно.
Алгоритм действий:
ВыгрузкаЗагрузкаДанныхXML.epf.Проанализируем возможные сложности при использовании XML: иногда при переносе документов 1С:Бухгалтерии возникают ошибки вида Вид субконто не доступен для данной записи. Это происходит, если в целевой базе еще не настроены параметры учета или план счетов. Чтобы этого избежать, сначала перенесите настройки (константы и учетную политику), а уже потом — документы.
Если вы хотите точно понять, какая таблица вызывает сбой, рассмотрите возможность использования технологического журнала (ТЖ) или SQL Server Profiler. При возникновении ошибки SDBL в ТЖ можно зафиксировать последний SQL-запрос. Имена таблиц в запросе (например, _Reference39) помогут сопоставить их с объектами метаданных 1С. Для получения соответствия имен используйте метод ПолучитьСтруктуруХраненияБазыДанных().
Например, выполните в консоли кода:
Структура = ПолучитьСтруктуруХраненияБазыДанных();
Для Каждого Стр Из Структура Цикл
Если Стр.ИмяТаблицыХранения = "_Node24" Тогда
Сообщить("Это объект: " + Стр.ИмяМетаданных);
КонецЕсли;
КонецЦикла;
Итог: Описанная проблема — это тяжелое наследие переходных периодов платформы. Наиболее эффективным методом является превентивное удаление устаревших планов обмена перед сменой режима совместимости. Если же база уже «сломана», используйте метод переноса данных через XML или откат на бэкап с последующей чисткой метаданных до наката обновления.