Oracle: Read-only access to the schema for another user?

六眼飞鱼酱① 提交于 2019-12-30 11:27:07

问题


I have a schema and a user with the same name: products. For development I would like to use it in a read-only mode from a java application. Therefore, I created a new user for the read-only application.

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;

Running the application I got the error that the table did not exist. Searching on the internet for solution, I came across SYNONYM. So I added synonym to the schema:

CREATE SYNONYM PRODUCTS_READONLY FOR PRODUCTS;

Now, I am getting this error in my java application:

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

What is wrong with my approach?

--UPDATE--

Seems like creating synonyms for schema was removed in 10g (Oracle: is it possible to create a synonym for a schema?). If I create schema for each object in the target schema, I would have to do the same every time a table is added to the target schema or any other changes to the any other objects in the target schema? That sounds cumbersome...

--UPDATE 2--

Seems like a trigger with alter session is a possible solution, but will it make the tables read-only so long the user has only SELECT privilege?


回答1:


If you have control over the way your application connects (e.g. an initialization statement for your connection pool), all you need to do is run:

ALTER SESSION SET CURRENT_SCHEMA = PRODUCTS;

From that point onward (during the lifetime of the session) any unqualified object name will be searched for in the PRODUCTS schema.

All grants given to PRODUCTS_READONLY will be in effect. The session will run under the credentials (and security restrictions) of the original user used to log in.

If you can not change the way the connection is established or initialized a logon trigger should also accomplish this:

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;
/

Note that it's crucial to trap any exception, because otherwise a potential error in the executed SQL will effectively log everyone out off the database. So use with care and test it well before putting that into production.




回答2:


I am not sure you can create a synonym for schema.

But you can create a synonym for every object in the remote schema, e.g.

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;

Don't be confused with table_name, it handles all types of objects there.



来源:https://stackoverflow.com/questions/21706260/oracle-read-only-access-to-the-schema-for-another-user

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!