В Oracle: как я могу определить, будет ли запрос SQL вызывать изменения без его выполнения? - PullRequest
4 голосов
/ 21 октября 2010

У меня есть строка, содержащая инструкцию SQL. Я хочу выяснить, будет ли запрос изменять данные или структуру базы данных, или он будет только читать данные. Есть ли способ сделать это?

Подробнее: в нашем приложении нам нужно разрешить пользователям вводить SQL-запросы, в основном как часть системы отчетов приложений. Этим SQL-запросам должно быть разрешено читать все, что им нравится, из базы данных, но им нельзя позволять что-либо изменять. Никаких обновлений, удаление вставок, удаление таблиц, удаление ограничений и т. Д.

На данный момент я только проверяю, является ли первое слово в строке «select», но это слишком сжато и слишком небезопасно.

Ответы [ 6 ]

10 голосов
/ 21 октября 2010

Вы должны предоставить только привилегии выбора в своих таблицах для логина, используемого приложением, чтобы быть уверенным.

9 голосов
/ 21 октября 2010

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

«Обычная» часть вашего приложения все еще сможет выполнять другие операции (вставка, обновление, удаление). Просто для составления отчетов будет использоваться пользователь только для чтения.

Как предполагает Хорасио, это также хорошая идея / практика добавлять «обёрточные» представления, которые раскрывают только то, что вы хотите показать. Какой-то "публичный API". Это может дать вам гибкость, если вам нужно изменить базовые таблицы и не хотите / не можете изменить отчеты на новые определения указанных таблиц. Это может, однако, рассматриваться как большая «дополнительная работа».

3 голосов
/ 21 октября 2010

Я согласен с другими, что правильное решение - использовать отдельную схему с ограниченным доступом и привилегиями для тех запросов, которые должны быть доступны только для чтения.

Однако другой вариант - установить транзакцию только для чтения перед выполнением оператора, введенного пользователем (SET TRANSACTION READ ONLY).

2 голосов
/ 21 октября 2010

Создайте VIEWS для предоставления данных конечным пользователям, это заслуживает внимания из-за трех вещей:

  1. Конечный пользователь не знает, как выглядит ваша база данных.
  2. Вы можете предоставить более простой способ извлечения некоторых фрагментов данных.
  3. Вы можете создать представление с ограничением только для чтения:
    CREATE VIEW items (name, price, tax)
          AS SELECT name, price, tax_rate
          FROM item
          WITH READ ONLY;
1 голос
/ 22 октября 2010

SELECT * FROM table FOR UPDATE работает даже при наличии только привилегии SELECT и все еще может причинить большой ущерб. Если вы хотите быть в безопасности, лучше использовать транзакции только для чтения.

1 голос
/ 22 октября 2010

Что-то, что хорошо работало для меня в прошлом, но может не подходить для вашей ситуации:

  • Использование хранимых процедур для реализации API для приложения. Все изменения выполняются через этот API. Все процедуры, представленные внешнему интерфейсу, являются законченными единицами работы, и эти процедуры отвечают за соблюдение прав.
  • Пользователям, запускающим интерфейсное приложение, разрешается только вызывать хранимые процедуры API и читать данные.
  • Поскольку предоставляемый API выполняет завершенные единицы работы, которые соответствуют действиям, которые пользователь может выполнять через графический интерфейс, то, позволяя им запускать процедуры напрямую, не дает им никаких дополнительных возможностей и не допускает случайного повреждения базы данных. *
...