Сравнение с хранимым процедурам СУБД и прямому SQL-доступу ролей

Запрос как хранимая процедура: серверная логика и права в Интеграме

хранимым процедурам СУБД и прямому SQL-доступу ролей

Обложка статьи: Запрос как хранимая процедура

Запрос Интеграма — единица серверной логики, аналог хранимой процедуры классической СУБД: он не только читает данные, но и меняет их, хранится в самой базе и выполняется с правами своего автора. Роль получает грант на сам запрос, а не на таблицы-источники; массовые изменения идут в два шага — превью и подтверждение; галка InTransaction выполняет весь вызов одной транзакцией «всё или ничего».

У каждой рабочей базы рано или поздно появляется логика, которую нельзя отдавать в руки пользователей: статус «Согласован» должен ставить только ответственный процесс, а не аккуратный менеджер; внешняя система должна получить данные одного отчёта, но не таблицы; массовая обработка тысячи записей не должна оставаться наполовину при сбое посреди прогона. Классическое решение этой развилки — хранимые процедуры: логика живёт в базе, выполняется на сервере, а ролям выдают право вызвать процедуру, не открывая таблицы. В no-code-конструкторах аналога обычно нет, и логика уезжает в код внешних скриптов — вместе с правами, журналом и знанием схемы. В Интеграме эту роль играет запрос: он читает и меняет данные, хранится записями базы и выполняется с правами автора.

Контекст

Запрос как хранимая процедура нужен там, где действие важнее просмотра. Типичные симптомы:

  • поле роли видно, но менять руками нельзя: статус «Согласован» и дату согласования ставит только кнопка;
  • внешней системе нужны данные одного отчёта по расписанию, а доступ к таблицам ей выдавать не хочется;
  • разовую обработку — нормализацию названий, разметку токенами — придётся перезапускать, и она должна переживать повторный прогон;
  • обновление пачки записей не должно оставаться наполовину выполненным, если вызов упал на середине.

Вопросы и ответы

Чем запрос Интеграма похож на хранимую процедуру?

Тем же, чем хранимая процедура в классической СУБД: логика хранится в базе, выполняется на сервере с правами автора, а ролям выдают право вызвать её, не открывая таблицы. Запрос дополнительно читает и меняет данные, делает HTTP-вызовы и правится без выкладки кода.

Почему маска роли не применяется к отчёту?

Потому что запрос выполняется с правами своего автора: его результат — ровно то, что автор задал колонками и условиями, и в этом смысл модели. Маски строк и закрытые колонки действуют при прямом доступе к таблицам и карточкам; к запросу роль получает один грант и видит только его результат.

Как разрешить роли менять поле, закрытое для ручного изменения?

Сделать поле только для чтения в роли и поставить его кнопкой через изменяющий запрос: колонка «Присвоить» записывает значение, вызов идёт POST-ом с confirmed=1 под правами автора запроса. Так устроено согласование: статус и дату ставит только кнопка, руками — никак.

Что произойдёт, если массовое обновление упадёт на середине?

Без специальной галки — останутся записи, изменённые до сбоя; их выручают идемпотентный фильтр «ещё не обработанные» и журнал с состоянием до и после. С галкой InTransaction весь вызов — одна транзакция: сбой откатывает уже записанное целиком.

Чем EXECUTE отличается от подтверждения confirmed?

Подтверждённый вызов двухшаговый: сначала превью «было ⇒ станет», затем POST с confirmed=1 и проверкой XSRF. EXECUTE снимает оба шага — запрос выполняется при любом вызове без подтверждения, и если он встроен в страницу, срабатывает при каждом открытии. Для опасных присвоений оставляйте двухшаговый вызов.

Как дать внешней системе доступ к одному отчёту?

Завести ей учётную запись с грантом на сам запрос: система будет забирать данные адресом report/<имя>?JSON_KV по расписанию и не получит доступа к таблицам. Внутреннюю структуру запроса можно менять, сохраняя колонки, — потребители не заметят.