Как исправить ошибку SDBL «Таблица или поле не содержится в разделе FROM» при добавлении измерения регистра в мобильном приложении 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке и активном сопровождении мобильных приложений на платформе 1С:Предприятие разработчики часто сталкиваются со специфическим поведением локальной СУБД SQLite. Одной из наиболее неприятных проблем является сбой реструктуризации базы данных при изменении метаданных. Типичный сценарий: в регистр сведений, который включен в состав плана обмена, добавляется новое измерение. После обновления конфигурации и попытке записи в этот регистр система аварийно завершает работу с сообщением:

«Ошибка SDBL: Таблица или поле (Fld336) не содержится в разделе FROM»

В этой статье мы подробно разберем, почему возникает этот сбой, проанализируем внутренние механизмы платформы и рассмотрим несколько практических способов решения проблемы — от простых "костылей" до системных подходов.

Техническая суть проблемы: почему падает SDBL?

Для того чтобы понять природу ошибки, заглянем "под капот" платформы 1С. Аббревиатура SDBL расшифровывается как Simple Data Base Layer — это промежуточный логический слой платформы, который транслирует запросы на языке 1С в физические SQL-запросы к конкретной СУБД (в случае мобильной платформы — к SQLite).

Когда объект метаданных (например, регистр сведений) включается в состав плана обмена, платформа автоматически создает в базе данных служебную таблицу для регистрации изменений. Физическое имя этой таблицы в базе данных начинается с префикса _InfoRgChngR (для регистров сведений). Эта таблица содержит ключевые поля (измерения) регистра, по которым фиксируются изменения для каждого узла обмена.

При добавлении нового измерения в регистр сведений платформа обязана выполнить реструктуризацию двух физических таблиц в файле базы данных SQLite мобильного устройства:

  1. Основной таблицы самого регистра (префикс _InfoRg).
  2. Таблицы регистрации изменений (префикс _InfoRgChngR).

В устаревших или проблемных релизах мобильной платформы (особенно ярко это выражено в ветке 8.3.15, например 8.3.15.62) механизм реструктуризации таблиц регистрации изменений в СУБД SQLite работает некорректно. Платформа успешно добавляет новое поле (например, _Fld336) в основную таблицу регистра, но "забывает" или некорректно добавляет его в таблицу регистрации изменений _InfoRgChngR.

В итоге возникает рассинхронизация: транслятор SDBL на логическом уровне "знает", что у регистра появилось новое измерение, и пытается построить SQL-запрос к таблице изменений с участием этого поля. Но физически в таблице SQLite этого поля нет. СУБД SQLite возвращает ошибку, которую SDBL транслирует разработчику в виде сообщения: «Таблица или поле не содержится в разделе FROM».

Подобные баги реструктуризации периодически возникают не только на мобильной, но и на десктопной платформе (например, известные баги платформы версий 8.3.24 / 8.3.25 при работе с расширениями и планами обмена).

---

Вариант 1. Дублирование и замена регистра (Метод "Чистого листа")

Если конфигурация уже находится на "живых" устройствах пользователей, и вам критически важно избежать их принудительного перезапуска или полной переустановки приложения, можно применить надежный обходной путь. Мы создаем новый регистр вместо модификации старого. Рассмотрим этот процесс по шагам:

  1. Проанализируем структуру проблемного регистра сведений. Допустим, он называется РегистрНоменклатура.
  2. Создадим в конфигураторе полную копию этого регистра и назовем его, например, РегистрНоменклатура_Новый.
  3. В новом регистре сразу же создадим все необходимые измерения, включая то самое новое измерение, из-за которого происходил сбой.
  4. Включим новый регистр РегистрНоменклатура_Новый в состав нужного плана обмена.
  5. Перенаправим все обращения в коде (чтение, запись, запросы) со старого регистра на новый. Старый регистр переименуем в РегистрНоменклатура_Устарел и снимем с него признак участия в плане обмена.
  6. При обновлении на мобильных устройствах платформа создаст абсолютно новые физические таблицы для РегистрНоменклатура_Новый и таблицы регистрации изменений для него. Поскольку реструктуризации "на лету" для новой таблицы не требуется, она создается с нуля в корректном виде, и ошибка SDBL не возникнет.

Этот костыль хорош тем, что он на 100% гарантирует бесконфликтное обновление у конечных пользователей без необходимости очистки данных.

---

Вариант 2. Двухэтапное обновление с отключением из плана обмена

Если плодить сущности в конфигурации не хочется, и вы желаете сохранить исходный регистр сведений, можно прибегнуть к двухэтапному обновлению конфигурации базы данных. Этот метод заставляет платформу полностью удалить, а затем заново создать таблицы регистрации изменений.

Разберем алгоритм действий:

  1. Этап 1: Извлечем регистр сведений из состава плана обмена в конфигураторе. Обновим базу данных и выпустим это обновление для мобильных клиентов. Когда пользователи обновятся, платформа физически удалит таблицу регистрации изменений _InfoRgChngR на мобильных устройствах, так как объект больше не участвует в обмене.
  2. Этап 2: В конфигураторе добавим новое измерение в регистр сведений и вернем регистр обратно в состав плана обмена. Выпустим второе обновление. При его установке мобильная платформа заново создаст таблицу регистрации изменений уже с учетом новой структуры и нового измерения.

Минус метода: Требует жесткого контроля за тем, чтобы все пользователи гарантированно установили промежуточное обновление (Этап 1) перед тем, как получат финальное (Этап 2).

---

Вариант 3. Очистка регистрации изменений перед обновлением

Иногда реструктуризация в SQLite проходит успешно, если сама таблица регистрации изменений на мобильном устройстве абсолютно пуста. Если в ней есть записи, SDBL пытается выполнить сложный перенос данных, на котором и спотыкается.

Мы можем попытаться программно очистить регистрацию перед тем, как обновить конфигурацию. Для этого на мобильном клиенте перед синхронизацией и загрузкой новой конфигурации можно выполнить следующий код:


// Выбираем узел, для которого зарегистрированы изменения
УзелОбмена = ПланыОбмена.ГлавныйУзел();
Если ЗначениеЗаполнено(УзелОбмена) Тогда
    // Полностью очищаем регистрацию изменений для нашего регистра
    ПланыОбмена.УдалитьРегистрациюИзменений(УзелОбмена, Метаданные.РегистрыСведений.РегистрНоменклатура);
КонецЕсли;

После очистки таблицы изменений закроем приложение и выполним обновление конфигурации. Пустая таблица реструктуризируется значительно легче и с меньшей вероятностью вызовет ошибку SDBL.

---

Вариант 4. Переустановка мобильного приложения (Очистка кэша и базы)

Самый простой, но радикальный метод — полная переустановка мобильного приложения на устройствах пользователей (или очистка данных приложения через настройки Android/iOS). При этом база данных SQLite создается заново с актуальной структурой "из коробки".

Важное предупреждение: Этот метод категорически не рекомендуется использовать в продакшене, если мобильное приложение работает в режиме офлайн и хранит на устройстве уникальные данные, которые еще не были отправлены на центральный сервер. Переустановка приведет к безвозвратной потере этих данных. Также это создаст неудобства для пользователей, которым придется заново проходить авторизацию и первичную инициализацию (создание начального образа базы данных).

---

Вариант 5. Обновление мобильной платформы

Поскольку корень проблемы кроется в ошибках конкретного релиза мобильной платформы, наиболее правильным системным решением является переход на более современные и стабильные версии платформы 1С.

Разработчиками 1С подобные ошибки реструктуризации SQLite были признаны и устранены в последующих ветках платформы. Рекомендуется поднять версию мобильной платформы до стабильных релизов веток 8.3.17, 8.3.18 или выше. При переходе на новые версии реструктуризация таблиц SQLite при добавлении измерений будет проходить в штатном автоматическом режиме без падений транслятора SDBL.

← На главную