2014-02-11 4 views
1

У меня есть схема и пользователь с таким же именем: products. Для разработки я хотел бы использовать его в режиме только для чтения из приложения Java. Поэтому я создал нового пользователя для приложения только для чтения.Oracle: доступ только для чтения к схеме для другого пользователя?

CREATE USER PRODUCTS_READONLY IDENTIFIED BY PRODUCTS_READONLY; 
GRANT CREATE SESSION to PRODUCTS_READONLY; 
BEGIN 
    FOR tab IN (SELECT table_name FROM all_tables WHERE owner = 'PRODUCTS') LOOP 
    EXECUTE IMMEDIATE 'GRANT SELECT ON PRODUCTS.'||tab.table_name||' TO PRODUCTS_READONLY'; 
    END LOOP; 
END; 

Запуск приложения У меня ошибка, что таблица не существует. Поиск в Интернете для решения, я наткнулся SYNONYM. Поэтому я добавил синоним к схеме:

CREATE SYNONYM PRODUCTS_READONLY FOR PRODUCTS; 

Теперь я получаю эту ошибку в моем java применения:

ERROR org.hibernate.util.JDBCExceptionReporter - ORA-17074 invalid name pattern.: PRODUCTS_READONLY.PRODUCT_TYPE

Что не так с моим подходом?

--UPDATE--

Кажется, создавая синонимы к схеме была удалена в 10г (Oracle: is it possible to create a synonym for a schema?). Если я создам схему для каждого объекта в целевой схеме, мне придется делать то же самое каждый раз, когда таблица добавляется в целевую схему или любые другие изменения в любые другие объекты в целевой схеме? Это звучит громоздко ...

--update 2--

Похоже, триггер с alter session является возможным решением, но он будет делать таблицы только для чтения, пока пользователь имеет только SELECT привилегии ?

+1

Почему бы не получить только чтение Подключение к вашей базе данных? (Подключение.setReadOnly (true);) – wumpz

+0

Я бы не касался приложения Java. У нас есть несколько уровней с фреймворками, и мы не используем связи явно. Я бы этого не делал, и мне интересно, можно ли достичь уровня базы данных. – user3111525

+0

@wumpz: В соответствии с JavaDocs 'setReadOnly()' - это всего лишь * подсказка * для драйвера для «* включения оптимизации базы данных *», а быстрый тест показывает, что это не мешает выполнению операторов DML. –

ответ

2

Если у вас есть контроль над тем, как ваши подключает приложения (например, оператор инициализации для пула соединений), все, что вам нужно сделать, это запустить:

ALTER SESSION SET CURRENT_SCHEMA = PRODUCTS; 

С этого момента (в течение времени жизни сеанс) любое неквалифицированное имя объекта будет искать в схеме PRODUCTS.

Все гранты, выданные PRODUCTS_READONLY, будут действовать. Сессия будет работать под учетными данными (и ограничений безопасности) исходного пользователя, используемого войти в

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

create or replace trigger logon_trg 
    after logon on database 
begin 
    if (user = 'PRODUCTS_READONLY') then 
     execute immediate 'alter session set current_schema = products'; 
    end if; 
exception 
    when others then null; -- prevent a login failure due to an exception 
end logon_trg; 
/

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

0

Я не уверен, что вы можете создать синоним схемы.

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

begin 
    for c in (select t.table_name from table_privileges t where grantee = 'PRODUCTS_READONLY') loop 
    execute immediate 'create synonym '||c.table_name||' for PRODUCTS.'||c.table_name; 
    end loop; 
end; 

Не путайте с именем table_name, он обрабатывает все типы объектов.

+0

Когда я вхожу в систему как product_readonly и выполняю оператор, я получаю сообщение об ошибке «таблица или представление не существует». – user3111525

+0

Обновлен мой вопрос. – user3111525

Смежные вопросы