Monday, September 04, 2006

How to make Oracle Table Read only?
(For complete details refer: http://www.dizwell.com/prod/node/60)
  • You could lock the table in exclusive mode. But the lock disappears, and DML resumes, when the locking session terminates.
connect / as sysdbalock table scott.emp in exclusive mode;
connect scott/tiger
select sum(sal) from emp;
SUM(SAL)
----------29025
update emp set sal=sal*2;
[session hangs]
  • You could simply revoke DML privileges on a table from all users, but risk forgetting one or two, or risk the possibility of a user hacking into the database with higher privileges.
create or replace function lockme
(object_schema in varchar2, object_name in varchar2)
return varchar2 is predicate varchar2(20);
begin predicate := '1=2';
return predicate;
end;
/
exec dbms_rls.add_policy('SCOTT','EMP','LCKPOL',-'SCOTT','LOCKME',’INSERT, UPDATE, DELETE’)

This creates a function which returns a never-true predicate (that is, 1 never equals 2), and uses Oracle’s Virtual Private Database functionality to attach a policy to the table which causes the function to fire and to append that predicate to whatever DML-style SQL is issued against the EMP table. Selects should be fine, however:
SYS is exempt from Virtual Private Database policies. Your table really isn’t made read-only by this technique -merely protected from casual DML issued by ordinary users. Which might genuinely be all that you neded. But if the reason you wanted to make the table read-only was to prevent any modification of this table’s data, then this mechanism (clever and convenient as it is) fails that test. The DBA can always by-pass the mechanism.

  • You could create a 'no DML' trigger, but risk the trigger being dropped or invalidated, and hence by-passed, by an ordinary user.
create or replace trigger lock_emp
before insert or update or delete on scott.emp
begin
raise_application_error(-20001, 'EMP is now Read-Only');
end;
/
  • You could apply a VPD policy to the table, but that never applies to SYS

  • You could make the table's tablespace read-only, and rely on auditing to let you know if an administrator tries to change that status (capturing the culprit after the event)
alter tablespace ro_tables read only;
alter tablespace ro_tables read write; (to restore)
  • You could truly lock down the table by moving it to read-only tablespace and burning the data files involved onto physically read-only media. That is un-circumventable by anyone.

No comments: