调用者权限 / 定义者权限 (1)

对于pl/sql子程序的调用来说,具有两种方式:定义者权限和调用者权限。
所谓定义者权限,表示的是在执行pl/sql子程序的时候,参考的是创建该pl/sql子程序的用户所拥有的权限。同时,pl/sql子程序在执行时,对于牵涉到的表或者其他对象,也都参考创建该pl/sql子程序的用户所拥有的对象。而执行该pl/sql子程序的用户不需要具有访问创建该pl/sql子程序的用户下的表的权限。缺省情况下,pl/sql子程序都以定义者权限来执行。

比如:
SQL> connect / as sysdba
已连接。
SQL> create user u1 identified by u1;

用户已创建

SQL> grant create session to u1;

授权成功。

SQL> connect u1/u1
已连接。
SQL> select last_name from hr.employees where employee_id=101;
select last_name from hr.employees where employee_id=101
                         *
ERROR 位于第 1 行:
ORA-00942: 表或视图不存在

SQL> connect hr/hr
已连接。
SQL> CREATE OR REPLACE PROCEDURE p_get_lastname
  2  (v_employee_id IN employees.employee_id%TYPE,
  3  v_last_name OUT employees.last_name%TYPE) IS
  4  BEGIN
  5    SELECT last_name
  6    INTO v_last_name
  7    FROM employees
  8    WHERE employee_id = v_employee_id;
  9  END;
 10  /

过程已创建。

SQL> grant execute on p_get_lastname to u1;

授权成功。

SQL> connect u1/u1
已连接。
SQL> var ls_lastname varchar2(50);
SQL> exec hr.p_get_lastname(101,:ls_lastname);

PL/SQL 过程已成功完成。

SQL> print ls_lastname;

LS_LASTNAME
----------------------------------------------
Kochhar

可以很明显看到,定义者权限中,u1没有权限查看hr.employees表里的数据,但是u1具有执行hr.p_get_lastname的权限,从而它可以获取hr.employees表里的记录。

而定义者权限则不同。它在执行pl/sql子程序的时候,参考的是执行者的权限。同时,pl/sql子程序在执行时,对于牵涉到的表或者其他对象,也都参考执行该pl/sql子程序的用户所拥有的对象。
比如:
SQL> connect / as sysdba
已连接。
SQL> create user u2 identified by u2 ;

用户已创建

SQL> grant create session to u2;

授权成功。

SQL> connect hr/hr
已连接。
SQL> CREATE OR REPLACE PROCEDURE p_get_lastname2
  2  (v_employee_id IN employees.employee_id%TYPE,
  3  v_last_name OUT employees.last_name%TYPE)
  4  authid current_user
  5  IS
  6  BEGIN
  7    SELECT last_name
  8    INTO v_last_name
  9    FROM employees
 10    WHERE employee_id = v_employee_id;
 11  END;
 12  /

过程已创建。

注意,这里添加的authid current_user就表示该存储过程为调用者权限。

SQL> grant execute on p_get_lastname2 to u2;

授权成功。

SQL> connect u2/u2
已连接。
SQL> var ls_lastname varchar2(50);
SQL> exec hr.p_get_lastname2(101,:ls_lastname);
BEGIN hr.p_get_lastname2(101,:ls_lastname); END;

*
ERROR 位于第 1 行:
ORA-00942: 表或视图不存在
ORA-06512: 在"HR.P_GET_LASTNAME2", line 7
ORA-06512: 在line 1

可以看的很清楚,这里的错误为:ORA-00942: 表或视图不存在。实际也就是hr.p_get_lastname2里访问的employees表不存在于当前u2用户下。

SQL> connect / as sysdba
已连接。
SQL> grant create table to u2;

授权成功。

SQL> alter user u2 quota 5M on users;

用户已更改。

SQL> connect u2/u2
已连接。

SQL> create table employees(employee_id number,last_name varchar2(50)) tablespace users;

表已创建。

SQL> insert into employees values(101,'hansijie');

已创建 1 行。

SQL> commit;

提交完成。

SQL> exec hr.p_get_lastname2(101,:ls_lastname);

PL/SQL 过程已成功完成。

SQL> print ls_lastname;

LS_LASTNAME
-------------------------------------------------
hansijie

可以看到,当我在u2下创建了employees表以后,就会访问到u2下的employees表里的记录了。

对于定义者权限的pl/sql子程序来说,通过角色传入的权限是不能作用于存储过程里面的。比如:
SQL> create user red identified by red;

用户已创建

SQL> grant dba to red;

授权成功。

SQL> connect red/red
已连接。
SQL> create or replace procedure p_test
  2  is
  3  begin
  4     dbms_utility.exec_ddl_statement('grant dba to u1');
  5  end;
  6  /

过程已创建。

SQL> exec p_test;
BEGIN p_test; END;

*
ERROR 位于第 1 行:
ORA-01031: 权限不足
ORA-06512: 在"SYS.DBMS_SYS_SQL", line 826
ORA-06512: 在"SYS.DBMS_SQL", line 32
ORA-06512: 在"SYS.DBMS_UTILITY", line 550
ORA-06512: 在"RED.P_TEST", line 4
ORA-06512: 在line 1

这时可以看到,说的很清楚,权限不足。但是red用户已经具有了dba权限了,为何还会报权限不足呢?这就是因为这是一个定义者权限的pl/sql子程序,在执行grant dba to u1的时候,不能获得dba这个角色所传递过来的权限。你可以把该存储过程改为调用者权限,表示参考调用者所拥有的权限。

SQL> create or replace procedure p_test
  2  authid current_user
  3  is
  4  begin
  5     dbms_utility.exec_ddl_statement('grant dba to u1');
  6  end;
  7  /

过程已创建。

SQL> exec p_test;

PL/SQL 过程已成功完成。

这时就能正确执行了。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/523774/viewspace-374309/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/523774/viewspace-374309/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值