一个简单的例子:
SQL> conn / as sysdba
已连接。
SQL> create user naruto identified by naruto;
用户已创建。
SQL> grant dba to naruto;
授权成功。
SQL> conn naruto/naruto
已连接。
SQL> create or replace procedure get_row --定义者权限
2 is
3 x number;
4 begin
5 execute immediate 'select 1 from dba_users where rownum = 1';
6 end;
7 /
过程已创建。
编译通过了,在这里过程里用到了动态sql,在编译时并不解释动态sql。
SQL> exec get_row;
BEGIN get_row; END;
*
第 1 行出现错误:
ORA-00942: 表或视图不存在
ORA-06512: 在 "NARUTO.GET_ROW", line 5
ORA-06512: 在 line 1
错误很明显,dba_users表不存在,但是naruto用户已经有dba权限了,为什么还看不到这张表?
因为过程只在 直接授权 下运行,不是通过一个角色来授权(例如 grant select on dba_users to naruto就可以运行)。
SQL> create or replace procedure get_row
2 authid current_user --改为调用者权限
3 is
4 x number;
5 begin
6 execute immediate 'select 1 from dba_users where rownum = 1';
7 end;
8 /
过程已创建。
SQL> exec get_row;
PL/SQL 过程已成功完成。
创建过程和运行过程所有角色都是禁用的
SQL> create or replace procedure haha
2 authid current_user
3 is
4 begin
5
6 for i in (select * from session_roles) loop
7 dbms_output.put_line(i.role);
8 end loop;
9 end;
10 /
过程已创建。
SQL> exec haha;
PL/SQL 过程已成功完成。
SQL> set serveroutput on
SQL> exec haha;
DBA
SELECT_CATALOG_ROLE
HS_ADMIN_ROLE
EXECUTE_CATALOG_ROLE
DELETE_CATALOG_ROLE
EXP_FULL_DATABASE
IMP_FULL_DATABASE
GATHER_SYSTEM_STATISTICS
SCHEDULER_ADMIN
WM_ADMIN_ROLE
JAVA_ADMIN
JAVA_DEPLOY
XDBADMIN
XDBWEBSERVICES
OLAP_DBA
AQ_ADMINISTRATOR_ROLE
MGMT_USER
PL/SQL 过程已成功完成。
SQL> create or replace procedure haha
2 is
3 begin
4
5 for i in (select * from session_roles) loop
6 dbms_output.put_line(i.role);
7 end loop;
8 end;
9 /
过程已创建。
SQL> exec haha;
PL/SQL 过程已成功完成。