I saw this post on Richard foote's blog which pointed me to this otn thread.
So i gave it a try. This is what i did.
Say I have a table as given below in production.
SQL> CREATE TABLE hx_my_read_only_table (no INTEGER CHECK(NO>0), name VARCHAR2(100));
Table created.
SQL> INSERT INTO hx_my_read_only_table VALUES(1,'KARTHICK');
1 row created.
SQL> INSERT INTO hx_my_read_only_table VALUES(2,'VIMAL');
1 row created.
SQL> INSERT INTO hx_my_read_only_table VALUES(3,'VIJAY');
1 row created.
SQL> COMMIT;
Commit complete.
SQL> SELECT * FROM hx_my_read_only_table;
NO NAME
---------- --------------------------------------------------------------------------------
1 KARTHICK
2 VIMAL
3 VIJAY
And I want to make it read only. I will use ACCESS CONTROL to achieve it.
SQL> CREATE CONTEXT hx_my_context USING hx_my_pkg;
Context created.
SQL> CREATE OR REPLACE PACKAGE hx_my_pkg
2 AS
3 PROCEDURE hx_set_context (
4 hx_p_fld VARCHAR2,
5 hx_p_value VARCHAR2);
6
7 FUNCTION hx_get_val (
8 hx_p_fld varchar2) RETURN NUMBER;
9
10 FUNCTION hx_get_key(
11 p_schema in varchar2,
12 p_object in varchar2) RETURN VARCHAR2;
13 END hx_my_pkg;
14 /
Package created.
SQL> CREATE OR REPLACE PACKAGE BODY hx_my_pkg
2 AS
3 PROCEDURE hx_set_context (
4 hx_p_fld VARCHAR2,
5 hx_p_value VARCHAR2)
6 IS
7 BEGIN
8 DBMS_SESSION.SET_CONTEXT('HX_MY_CONTEXT', hx_p_fld, hx_p_value);
9 END;
10
11 FUNCTION hx_get_val (
12 hx_p_fld varchar2) RETURN NUMBER
13 IS
14 BEGIN
15 RETURN SYS_CONTEXT('HX_MY_CONTEXT', hx_p_fld);
16 END;
17
18 FUNCTION hx_get_key(
19 p_schema in varchar2,
20 p_object in varchar2) RETURN VARCHAR2
21 IS
22 lPredicate VARCHAR2 (2000);
23 BEGIN
24 lPredicate := 'NO = SYS_CONTEXT(''HX_MY_CONTEXT'', ''NO'')';
25
26 RETURN lPredicate;
27 END;
28
29 END hx_my_pkg;
30 /
Package body created.
SQL> BEGIN
2 DBMS_RLS.ADD_POLICY (USER, 'HX_MY_READ_ONLY_TABLE', 'HX_READ_ONLY_POLICY',USER, 'hx_my_pkg.hx_get_key', 'INSERT, UPDATE, DELETE' );
3 END;
4 /
PL/SQL procedure successfully completed.
SQL> BEGIN
2 hx_my_pkg.hx_set_context('NO',0);
3 END;
4 /
PL/SQL procedure successfully completed.
SQL> UPDATE hx_my_read_only_table
2 SET NAME = 'RICHARD'
3 WHERE NO = 1;
0 rows updated.
SQL> DELETE FROM hx_my_read_only_table;
0 rows deleted.
SQL> INSERT INTO hx_my_read_only_table VALUES(4,'RICHARD');
1 row created.
I was expecting this one not to insert record. I have to see what the problem is.
SQL> ROLLBACK;
Rollback complete.
Mean while I restricted the insert by with this trigger. I personally hate triggers but....
SQL> CREATE OR REPLACE TRIGGER hx_my_trigger BEFORE INSERT ON hx_my_read_only_table FOR EACH ROW
2 BEGIN
3 IF :NEW.NO <> hx_my_pkg.hx_get_val('NO')
4 THEN
5 RAISE_APPLICATION_ERROR(-20001, 'Insert Not possible...');
6 END IF;
7 END;
8 /
Trigger created.
SQL> INSERT INTO hx_my_read_only_table VALUES(4,'RICHARD');
INSERT INTO hx_my_read_only_table VALUES(4,'RICHARD')
*
ERROR at line 1:
ORA-20001: Insert Not possible...
ORA-06512: at "SYSADM.HX_MY_TRIGGER", line 4
ORA-04088: error during execution of trigger 'SYSADM.HX_MY_TRIGGER'
So i have Restricted INSERT, UPDATE, DELETE on this table.
SQL> SELECT * FROM HX_MY_READ_ONLY_TABLE;
NO NAME
---------- --------------------------------------------------------------------------------
1 KARTHICK
2 VIMAL
3 VIJAY
Subscribe to:
Post Comments (Atom)
2 comments:
But a quick warning for sql*loader direct path load since it ignores the triggers.
An example for this behaviour;
http://tinyurl.com/3zfmzs
thank you tonguch that was a very useful information
Post a Comment