В процессе обновления конфигурации, переноса баз данных между компьютерами или при аварийном завершении работы платформы 1С:Предприятие разработчики часто сталкиваются с аппаратными и логическими сбоями СУБД. Одними из самых неприятных и труднодиагностируемых ошибок являются сообщения вида «В схеме базы данных отсутствует таблица "InfoRgХХХ"» и сопутствующая ей при попытке тестирования СУБД «Ошибка SDBL: Выход за пределы размерности результата».
В этой статье мы подробно разберем природу данных ошибок, выясним, почему они возникают как в файловых, так и в клиент-серверных базах данных, рассмотрим пошаговые алгоритмы их устранения, а также затронем важные архитектурные вопросы проектирования уникальных идентификаторов (кодов) в справочниках 1С.
---
Для начала давайте разберемся с терминологией платформы 1С. Имя таблицы InfoRg455 (или аналогичное с другим числовым индексом) расшифровывается как Information Register — то есть физическая таблица СУБД, предназначенная для хранения данных конкретного Регистра сведений. Число 455 — это внутренний идентификатор метаданных в конкретной конфигурации базы данных.
Ошибка «В схеме базы данных отсутствует таблица...» означает, что в специальной системной таблице DBSchema (которая хранит логическое описание структуры всей базы данных) запись о регистре сведений присутствует, однако на физическом уровне в СУБД (или в файле 1Cv8.1CD для файловой базы) этой таблицы просто нет. Это классический пример рассинхронизации логической и физической структуры данных.
К основным причинам такого сбоя относятся:
DBSchema и Config.---
Прежде чем приступать к исправлению, нам необходимо понять, какому именно объекту метаданных в дереве конфигурации соответствует поврежденная таблица InfoRg455. Для этого мы можем запустить встроенную функцию платформы ПолучитьСтруктуруХраненияБазыДанных().
Давайте напишем небольшую внешнюю обработку или запустим код в режиме отладки в режиме «1С:Предприятие» для поиска имени объекта:
СтруктураХранения = ПолучитьСтруктуруХраненияБазыДанных();
Для Каждого СтрокаТаблицы Из СтруктураХранения Цикл
Если Найти(СтрокаТаблицы.ИмяТаблицыХранения, "InfoRg455") > 0 Тогда
Сообщить("Имя поврежденного регистра в конфигураторе: " + СтрокаТаблицы.ИмяМетаданных);
Сообщить("Назначение таблицы: " + СтрокаТаблицы.Назначение);
КонецЕсли;
КонецЦикла;
Зная имя конкретного регистра сведений, нам будет гораздо проще локализовать проблему и применить точечные методы исправления.
---
Рассмотрим несколько эффективных решений проблемы, от самых простых пользовательских до глубоких административных.
Как показывает практика практикующих разработчиков, в большинстве простых случаев файловых баз помогает полное пересоздание локального кэша и структуры файлов базы данных через механизм резервного копирования. Выполним следующие действия:
.dt..dt.При загрузке файла .dt платформа заново физически инициализирует все таблицы СУБД, строго опираясь на логическое описание метаданных. Недостающая таблица InfoRg455 будет создана с нуля.
Если база данных большая или находится в клиент-серверном варианте, выгрузка-загрузка .dt может занять слишком много времени. В таком случае мы можем заставить платформу принудительно перестроить физическую структуру поврежденного регистра:
ЦеныНоменклатуры).Булево или изменим длину строкового ресурса на 1 символ.InfoRg455.Если база является файловой, то причиной отсутствия таблицы часто выступает повреждение внутренней структуры самого файла базы данных 1Cv8.1CD на физическом уровне (из-за сбойных секторов жесткого диска, отключения питания или сбоев оперативной памяти без поддержки ECC). Для лечения таких сбоев предназначена стандартная утилита от фирмы 1С.
C:\Program Files\1cv8\имя_релиза_платформы\bin\).1Cv8.1CD.---
Данная ошибка часто возникает при попытке выполнить встроенное Тестирование и исправление (ТИИ) поврежденной базы. Технологически SDBL (Simple Data Base Layer) — это внутренний слой абстракции платформы 1С, который транслирует запросы к СУБД. Ошибка переполнения размерности чаще всего связана со сбоем в таблицах регистрации изменений конфигурации при использовании планов обмена (например, в РИБ).
Когда вы пытаетесь запустить реструктуризацию или ТИИ, платформа пытается обработать огромные объемы накопленных служебных таблиц изменений конфигурации (таблицы с именами _ConfigChngR и _ConfigChngR_ExtProps). Если количество необработанных регистраций превышает критический лимит (обычно десятки тысяч записей), буфер SDBL переполняется.
Решение проблемы для файловых баз:
Поскольку напрямую в файле 1Cv8.1CD выполнить SQL-запрос очистки невозможно, нам необходимо очистить регистрацию изменений программно. Мы можем воспользоваться встроенной в БСП (Библиотеку стандартных подсистем) обработкой «Регистрация изменений для обмена» или выполнить очистку с помощью короткого скрипта в режиме «1С:Предприятие»:
ПланыОбменаМенеджер = ПланыОбмена;
Для Каждого ПланОбмена Из Метаданные.ПланыОбмена Цикл
ВыборкаУзлов = ПланыОбмена[ПланОбмена.Имя].Выбрать();
Пока ВыборкаУзлов.Следующий() Цикл
// Пропускаем предопределенный узел (текущую базу)
Если ВыборкаУзлов.Ссылка = ПланыОбмена[ПланОбмена.Имя].ЭтотУзел() Тогда
Продолжить;
КонецЕсли;
// Очищаем регистрацию изменений конфигурации для узла
ПланыОбмена.УдалитьРегистрациюИзменений(ВыборкаУзлов.Ссылка, ПолучитьСтруктуруХраненияБазыДанных());
КонецЦикла;
КонецЦикла;
После удаления зависших регистраций изменений ошибка «Выход за пределы размерности результата» при реструктуризации и ТИИ полностью исчезает.
---
Обсуждая системные сбои, автор темы упомянул важную деталь, которая косвенно могла спровоцировать некорректную работу СУБД: использование отрицательных чисел в качестве строковых кодов справочника. Разберем, почему это является критической архитектурной ошибкой и как правильно спроектировать систему в подобных случаях.
В платформе 1С встроенный механизм автонумерации работает по строгому алгоритму. Когда тип кода справочника установлен как Строка, но значения в него записываются числовые (например, "100", "101"), платформа пытается выделить числовую часть из строки, увеличить ее на единицу и преобразовать обратно в строку для нового элемента.
Появление знака «минус» (например, "-455") полностью ломает этот алгоритм анализа строки. Платформа перестает корректно распознавать границы чисел, автонумерация сбивается, и при записи новых элементов код начинает сбрасываться в предельное значение (например, "999999999"). Это приводит к дублированию кодов, нарушению индекса уникальности справочника и, как следствие, к логическому разрушению базы данных.
Если вам по условиям технического задания или для интеграции со старыми внешними системами жизненно необходимо хранить отрицательные идентификаторы элементов, категорически запрещено использовать для этого стандартный реквизит Код!
Давайте разберем правильный паттерн проектирования:
Код оставляем с его системным назначением. Настраиваем тип кода как Число (или Строка с автонумерацией) и отдаем управление нумерацией полностью платформе 1С.ВнешнийКод) с типом Число (длина 10, включая знак минус).Посмотрим на пример реализации контроля уникальности в модуле объекта справочника:
Процедура ПередЗаписью(Отказ, РежимЗаписи)
// Исключаем проверку, если запись производится в процессе обмена данными
Если ЭтотОбъект.ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
// Проверим заполнение нашего кастомного внешнего кода
Если ЗначениеЗаполнено(ЭтотОбъект.ВнешнийКод) Тогда
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| СправочникОбъект.Ссылка КАК Ссылка
|ИЗ
| Справочник.ИмяВашегоСправочника КАК СправочникОбъект
|ГДЕ
| СправочникОбъект.ВнешнийКод = &ВнешнийКод
| И СправочникОбъект.Ссылка <> &ТекущаяСсылка";
Запрос.УстановитьПараметр("ВнешнийКод", ЭтотОбъект.ВнешнийКод);
Запрос.УстановитьПараметр("ТекущаяСсылка", ЭтотОбъект.Ссылка);
РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
Отказ = Истина;
ВызватьИсключение "Ошибка записи! Элемент с внешним отрицательным кодом "
+ Строка(ЭтотОбъект.ВнешнийКод) + " уже существует в базе данных.";
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Такой подход гарантирует стабильную и бесперебойную работу встроенных механизмов СУБД 1С, полностью исключает порчу уникальных индексов базы данных и при этом решает бизнес-задачу по хранению любых специфических идентификаторов из внешних систем.