Механизм расширений в платформе «1С:Предприятие 8.3» — это мощный инструмент, позволяющий кастомизировать типовые конфигурации без снятия их с поддержки. Однако при работе с расширениями на относительно старых версиях платформы (особенно веток 8.3.11 и 8.3.12) разработчики часто сталкиваются с критическими ошибками СУБД. Самые опасные из них возникают при попытке добавить новые объекты данных (справочники, документы) через расширение, изменить режим совместимости, а затем удалить это расширение или обновить конфигурацию.
В этой статье мы подробно разберем природу этих ошибок, выясним причины их возникновения и рассмотрим несколько надежных способов решения — от простого обхода через файловый режим до низкоуровневой работы с таблицами на SQL-сервере.
Обычно проблема заявляет о себе при попытке обновить конфигурацию базы данных или удалить расширение. Процесс прерывается одной из следующих ошибок:
SDBL (Simple Database Layer) — это внутренний уровень абстракции платформы 1С, транслирующий запросы метаданных в SQL-команды. Данный сбой является известным багом платформы в механизме реструктуризации. При удалении расширения, содержащего физические таблицы (свои справочники или документы), платформа некорректно формирует инструкции для работы с временными таблицами реструктуризации, что приводит к аварийному завершению операции СУБД.
Часто при попытке удалять объекты из расширения «по одному» в СУБД возникает конфликт уникальности индексов. Типичный текст ошибки выглядит так:
Microsoft SQL Server Native Client 11.0: Не удается вставить повторяющуюся строку ключа в объект "dbo._Reference470" с уникальным индексом "_Reference470_S_HPK". Повторяющееся значение ключа: (0, 0x068a00215ef0fe1611e1beb6fd1527c2).
Проанализируем эту ошибку:
dbo._Reference470 указывает на конкретный справочник в базе данных (префикс _Reference всегда соответствует справочникам)._S_HPK расшифровывается как System Hierarchy Parent Key (системный ключ родителя иерархии). Этот уникальный индекс СУБД создает автоматически для иерархических справочников. Он состоит из признака папки, идентификатора родительского элемента и GUID самого элемента.X1), которые при попытке реструктуризации пытаются объединиться с основными таблицами, вызывая дублирование уникальных ключей.Ниже мы рассмотрим три практических метода преодоления этой критической ситуации.
Файловая СУБД 1С (движок базы данных .1CD) устроена менее строго по сравнению с MS SQL Server в части контроля транзакционной целостности промежуточных индексов во время реструктуризации. Она позволяет безболезненно провести те операции удаления расширения, на которых SQL-сервер спотыкается.
Разберем этот процесс по шагам:
.dt..dt..dt.F7 (или кнопку «Обновить конфигурацию базы данных»). Файловая база должна успешно применить изменения и очистить структуру таблиц..dt. В Конфигураторе вашей рабочей SQL-базы загружаем этот файл. База данных успешно обновится на SQL-сервере без старых расширений и ошибок индексов.Если база данных имеет объем в сотни гигабайт, перенос ее в файловый вариант и обратно через .dt невозможен из-за ограничений файлового формата (размер одной таблицы не может превышать 4 ГБ) и огромных временных затрат. В этом случае мы должны решить проблему непосредственно на сервере СУБД с помощью SQL Server Management Studio (SSMS).
Проанализируем и выполним следующие шаги:
Шаг 1. Поиск дублирующихся записей. Нам необходимо выявить строки, которые вызывают сбой уникального индекса. Для этого выполним SQL-запрос к проблемной таблице (имя таблицы берем из текста вашей ошибки, например, _Reference470):
SELECT _Folder, _ParentIDRRef, _IDRRef, COUNT(*)
FROM dbo._Reference470
GROUP BY _Folder, _ParentIDRRef, _IDRRef
HAVING COUNT(*) > 1;
Этот запрос вернет строки, у которых комбинация полей иерархии дублируется. Запомните GUID проблемной записи из колонки _IDRRef.
Шаг 2. Удаление дубликатов. Чтобы безопасно удалить только одну из дублирующихся строк (оставив оригинал), применим обобщенное табличное выражение (CTE) с функцией ROW_NUMBER():
WITH CTE_Duplicates AS (
SELECT _Folder, _ParentIDRRef, _IDRRef,
ROW_NUMBER() OVER (PARTITION BY _Folder, _ParentIDRRef, _IDRRef ORDER BY _IDRRef) as RowNum
FROM dbo._Reference470
)
DELETE FROM CTE_Duplicates WHERE RowNum > 1;
Шаг 3. Временное удаление конфликтующего индекса. Если платформа 1С все равно отказывается обновлять конфигурацию из-за ошибок индексации на этапе реструктуризации, мы можем временно удалить уникальный индекс непосредственно в СУБД:
ALTER TABLE dbo._Reference470 DROP CONSTRAINT _Reference470_S_HPK;
-- Если индекс был создан как обычный некластеризованный:
-- DROP INDEX _Reference470_S_HPK ON dbo._Reference470;
Шаг 4. Обновление в Конфигураторе. Сразу после удаления индекса в СУБД переходим в Конфигуратор 1С и запускаем обновление конфигурации базы данных (клавиша F7). Платформа успешно завершит реструктуризацию, так как СУБД больше не блокирует запись из-за проверок уникальности.
Шаг 5. Восстановление индекса. Чтобы вернуть базу данных в штатное состояние и воссоздать индекс, запускаем Конфигуратор, переходим в Тестирование и исправление..., выбираем только пункт «Реиндексация таблиц» и запускаем выполнение. Платформа 1С автоматически пересоздаст удаленный SQL-индекс в правильном и чистом виде.
Иногда критический сбой реструктуризации SDBL вызывают зависшие транзакции регистрации изменений конфигурации. Для очистки этих данных выполним следующие действия в SSMS:
dbo._ConfigChngR и dbo._ConfigChngR_Hex.
TRUNCATE TABLE dbo._ConfigChngR;
TRUNCATE TABLE dbo._ConfigChngR_Hex;
dbo._Reference470X1), и принудительно удалим их (инструкция DROP TABLE), предварительно убедившись, что данные из расширения нам больше не нужны.Чтобы в будущем не столкнуться с подобными критическими сбоями реструктуризации, рекомендуем придерживаться следующих правил:
8.3.10, то и расширение должно работать строго в рамках этого режима.ПриСозданииНаСервере), добавляя новые элементы и кнопки динамически с помощью кода.8.3.15 и выше). Переход на современную стабильную версию платформы часто решает описываемые проблемы автоматически.