Ошибка «У пользователя недостаточно прав на исполнение операции над базой данных» является одной из самых коварных в практике разработчика и администратора 1С. Она часто сбивает с толку, так как возникает даже тогда, когда у пользователя, казалось бы, настроены все необходимые роли на чтение, запись и проведение документов. В этой статье мы подробно разберем природу данной ошибки, проанализируем причины её возникновения при работе механизма RLS (Row Level Security) и рассмотрим пошаговые инструкции по её устранению.
Чаще всего эта ошибка проявляется в конфигурациях с включенным ограничением прав на уровне записей (например, доступ только по «своей» организации). Рассмотрим типичную ситуацию: в базе ведется учет по нескольким организациям. Пользователь видит только данные своей компании. При попытке рассчитать средний заработок или провести документ начисления зарплаты система выдает отказ. Проблема заключается не в отсутствии прав на объект метаданных (справочник или документ), а в том, что SQL-запрос, который формирует платформа, пытается обратиться к данным, доступ к которым закрыт правилами RLS.
Проанализируем ситуацию: если документ за прошлый месяц проводится нормально, а за текущий выдает ошибку — значит, дело не в настройках ролей, а в конкретных данных. Для начала нам необходимо заглянуть в Журнал регистрации. Ищем события с категорией «Доступ — Отказ в доступе». Там часто можно найти подсказку: на какой именно регистр или таблицу «ругается» система.
Это самый быстрый метод «погасить» ошибку, если она возникает в самописных или измененных типовых запросах. Когда мы выполняем запрос без этого ключевого слова, платформа пытается прочитать все записи, подходящие под условия. Если среди них оказывается хотя бы одна строка, на которую у пользователя нет прав по RLS, выполнение всего запроса прерывается ошибкой.
Рассмотрим пример. Если мы видим затык в модуле ПроведениеРасчетовПереопределяемый, нам нужно найти текст запроса и добавить в него волшебное слово. Посмотрим на код:
Запрос = Новый Запрос;
// Было:
// Запрос.Текст = "ВЫБРАТЬ * ИЗ РегистрРасчета.ОсновныеНачисленияРаботниковОрганизаций";
// Стало:
Запрос.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ * ИЗ РегистрРасчета.ОсновныеНачисленияРаботниковОрганизаций";
Выборка = Запрос.Выполнить().Выбрать();
Важный нюанс: использование ВЫБРАТЬ РАЗРЕШЕННЫЕ просто отфильтрует недоступные данные. Если расчет среднего заработка требует данных по всей базе, результат может быть неполным. Однако в большинстве случаев для конкретной организации это решает проблему «вылета» системы.
Проанализируем более глубокую причину. Часто ошибка возникает из-за того, что в базе появились записи с пустой аналитикой или ссылками на объекты, которые не входят в разрешенные группы доступа. Например, если в регистре сведений «Реквизиты уплаты налогов» появилась запись с пустой организацией, то запрос RLS при попытке сравнить Организация = &РазрешенныеОрганизации может выдать ошибку исполнения операции над БД.
Выполним следующие шаги для исправления:
РегистрСведений.СведенияОбЭЛН или РегистрНакопления.ТоварыОрганизаций).Организация, Склад или ФизическоеЛицо (в зависимости от того, по чему настроен RLS).В зарплатных решениях часто возникает ошибка при обращении к виртуальной таблице ФактическийПериодДействия. Проблема здесь в том, что права на виртуальные таблицы наследуются от физических таблиц, но механизм построения запроса платформой может давать сбой, если условия вложенных запросов конфликтуют с правилами доступа.
Если ошибка возникает в коде вида:
ИЗ
РегистрРасчета.ОсновныеНачисленияРаботниковОрганизаций.ФактическийПериодДействия(
ВидРасчета В (&СписокВР) И (Сотрудник, ПериодДействия) В (&СотрудникиПериоды)
) КАК НачисленияФПД
Выясним причину через Консоль запросов. Попробуйте выполнить этот запрос под проблемным пользователем. Если консоль выдает ошибку SDBL или «Соединение не удерживает контекст», это явный признак того, что платформа не может построить эффективный план SQL-запроса с учетом RLS. В этом случае поможет либо установка привилегированного режима для данного участка кода, либо использование временных таблиц для предварительной фильтрации данных.
Если мы не хотим снимать конфигурацию с поддержки и вставлять РАЗРЕШЕННЫЕ в типовой код (что придется повторять при каждом обновлении), воспользуемся механизмом расширений. Мы можем перехватить процедуру, в которой выполняется проблемный запрос, и обернуть её выполнение в привилегированный режим.
Разберем пример создания расширения:
&ИзменениеИКонтроль или &Вместо.
&Вместо("РассчитатьСреднийЗаработок")
Процедура эк_РассчитатьСреднийЗаработок(Параметры)
УстановитьПривилегированныйРежим(Истина);
ПродолжитьВызов(Параметры);
УстановитьПривилегированныйРежим(Ложь);
КонецПроцедуры
В привилегированном режиме проверки RLS игнорируются, и запрос к базе данных выполняется от имени системы, что полностью снимает ошибку «недостаточно прав».
В платформе 8.3 существует два режима работы RLS: Стандартный и Производительный. В производительном режиме платформа кэширует ключи доступа во временных таблицах SQL. Иногда этот кэш становится неактуальным или содержит ошибки.
Попробуем переключить режим:
Часто простой переход на стандартный режим (хотя он и медленнее) исправляет труднообъяснимые ошибки доступа, связанные с вложенными запросами к регистрам расчета.
Иногда причина кроется в сохраненных фильтрах в списках документов. Если пользователь установил отбор по объекту, к которому у него позже отобрали права (например, по другой организации), при открытии формы списка система будет пытаться применить этот фильтр и упадет с ошибкой прав.
Рассмотрим порядок действий:
Также не забываем про очистку серверного кэша. Для этого достаточно перезапустить службу Агент сервера 1С:Предприятия или временно удалить базу из списка и добавить её снова (для очистки локального кэша пользователя).
Ошибка «У пользователя недостаточно прав на исполнение операции над базой данных» почти всегда является следствием конфликта между данными в базе и правилами RLS в запросе. Помните: установка полных прав — это не решение, а обход проблемы, который создает риски безопасности. Правильный путь — это либо очистка данных от пустых значений, либо использование конструкции ВЫБРАТЬ РАЗРЕШЕННЫЕ, либо перевод критичного кода в привилегированный режим работы.