Почему возникает ошибка «Внутренняя ошибка при реконструкции запроса (2)» при запуске внешней обработки?

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

В процессе разработки и эксплуатации внешних обработок в 1С:Предприятие 8.3 пользователи могут столкнуться с критической ошибкой, возникающей при выполнении запросов к базе данных, работающей на СУБД PostgreSQL. Текст ошибки обычно выглядит как «Ошибка SDBL: Внутренняя ошибка при реконструкции запроса (2)». Важной особенностью является то, что ошибка часто проявляется только у пользователей, не обладающих правами администратора, что напрямую указывает на конфликт системы прав доступа (RLS) и механизма формирования SQL-запросов платформой 1С.

Анализ причин возникновения ошибки

Рассмотрим, почему это происходит. При выполнении кода РезультатЗапроса = Запрос.Выполнить(); платформа 1С транслирует ваш объект Запрос в SQL-код для СУБД PostgreSQL. В случае использования RLS (ограничения прав на уровне записей), 1С в автоматическом режиме добавляет в запрос дополнительные условия проверки прав. Если структура запроса является сложной или база данных имеет специфическую конфигурацию, автоматическая трансляция может привести к превышению лимитов сложности запроса или некорректной интерпретации со стороны оптимизатора PostgreSQL, что и вызывает сбой на низком уровне SDBL.

Решение проблемы: Применение привилегированного режима

Основным способом устранения данной ошибки, который подтвердил автор темы, является использование привилегированного режима. Привилегированный режим позволяет временно отключить проверки прав доступа и RLS для текущего участка кода, тем самым исключая добавление «тяжелых» условий проверки прав в SQL-запрос.

Давайте разберем, как правильно реализовать этот подход:

  1. Перенесите логику выполнения запроса в серверную процедуру или функцию.
  2. Используйте метод УстановитьПривилегированныйРежим(Истина) непосредственно перед выполнением запроса.
  3. Обязательно обеспечьте корректное завершение работы в привилегированном режиме, вызвав УстановитьПривилегированныйРежим(Ложь) после завершения операции.

Посмотрим на пример реализации серверного вызова:


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

Важные рекомендации при работе с внешними обработками

При попытке борьбы с ошибками безопасности разработчики часто сталкиваются с использованием метода УстановитьБезопасныйРежим(Ложь). Важно понимать, что этот метод не является универсальным решением для ошибок SDBL. Более того, при попытке вызвать его в процедуре, где безопасный режим не был установлен платформой автоматически, вы получите ошибку исполнения. Поэтому для устранения проблем с RLS рекомендуется именно УстановитьПривилегированныйРежим.

Дополнительные методы оптимизации

Если использование привилегированного режима по политике безопасности компании нежелательно, рекомендуем обратить внимание на следующие аспекты:

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

← На главную