[oracle] Oracle - How to create a readonly user

It's possible create a readonly database user at an Oracle Database? How?

This question is related to oracle readonly

The answer is


create user ro_role identified by ro_role;
grant create session, select any table, select any dictionary to ro_role;

It is not strictly possible in default db due to the many public executes that each user gains automatically through public.


you can create user and grant privilege

create user read_only identified by read_only; grant create session,select any table to read_only;


Execute the following procedure for example as user system.

Set p_owner to the schema owner and p_readonly to the name of the readonly user.

create or replace
procedure createReadOnlyUser(p_owner in varchar2, p_readonly in varchar2) 
AUTHID CURRENT_USER is
BEGIN
    execute immediate 'create user '||p_readonly||' identified by '||p_readonly;
    execute immediate 'grant create session to '||p_readonly;
    execute immediate 'grant select any dictionary to '||p_readonly;
    execute immediate 'grant create synonym to '||p_readonly;

   FOR R IN (SELECT owner, object_name from all_objects where object_type in('TABLE', 'VIEW') and owner=p_owner) LOOP
      execute immediate 'grant select on '||p_owner||'.'||R.object_name||' to '||p_readonly;
   END LOOP;
   FOR R IN (SELECT owner, object_name from all_objects where object_type in('FUNCTION', 'PROCEDURE') and owner=p_owner) LOOP
      execute immediate 'grant execute on '||p_owner||'.'||R.object_name||' to '||p_readonly;
   END LOOP;
   FOR R IN (SELECT owner, object_name FROM all_objects WHERE object_type in('TABLE', 'VIEW') and owner=p_owner) LOOP
      EXECUTE IMMEDIATE 'create synonym '||p_readonly||'.'||R.object_name||' for '||R.owner||'."'||R.object_name||'"';
   END LOOP;
   FOR R IN (SELECT owner, object_name from all_objects where object_type in('FUNCTION', 'PROCEDURE') and owner=p_owner) LOOP
      execute immediate 'create synonym '||p_readonly||'.'||R.object_name||' for '||R.owner||'."'||R.object_name||'"';
   END LOOP;
END;