角色的确是一种很方便的权限集合组织方式,在很多系统中也是广泛应用。但是在Oracle中,使用角色权限role privilege是要格外小心的,特别是进行数据库开发过程中。因为Oracle存储过程等结构对角色权限有剔除效应。 【实验】 //建立实验角色r_cat_role SQL> create role r_cat_role ; Role created //授予系统权限select any dictionary给实验角色,select any dictionary权限可以访问到Oracle的大部分元数据视图。 SQL> grant select any dictionaryto r_cat_role; Grant succeeded //创建用户 SQL> create user mytest identified by mytest; User created SQL> grant create session to mytest; Grant succeeded SQL> grant r_cat_role to mytest; Grant succeeded SQL> grant create procedure to mytest; Grant succeeded SQL> conn mytest/mytest@ora11g; Connected to Oracle Database11gEnterpriseEdition Release11.2.0.1.0 Connected as mytest SQL> select count(*) fromdba_objects; COUNT(*) ---------- 72282 dba_objects视图是元数据字典的一个组成部分。mytest用户在接受角色权限r_cat_role之后,具有了在SQL中直接使用的权限。下面我们构造存储过程如下: SQL> create or replace procedure P_TEST_NC 2 is 3 n_res number; 4 begin 5 select count(*) 6 into n_res 7 from dba_objects; 8 9 dbms_output.put_line(to_char(n_res)); 10 end P_TEST_NC; 11 / Warning: Procedure created with compilation errors SQL> select * from user_errors; NAME TYPE SEQUENCE LINE POSITION TEXT ATTRIBUTE ---------- ------------ ---------- ---------- ---------- ---------------------------------------- --------- P_TEST_NC PROCEDURE 1 7 8 PL/SQL: ORA-00942:表或视图不存在 ERROR P_TEST_NC PROCEDURE 2 5 3 PL/SQL: SQL Statement ignored ERROR 编译报错,看起来不可思议。明明mytest用户具有dba_objects视图的访问权限,而且在SQL语句直接可以使用。我们说,就是因为访问dba_objects的权限是通过角色授予的。存储过程等Oracle代码结构具有一个特性,就是可以将用户的三层权限(role、system和object)中的role权限剥离掉。 |