pl/sql的定义者与调用者

联系:手机(+86 13429648788) QQ(107644445)QQ咨询惜分飞

标题:pl/sql的定义者与调用者

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

一、执行的schema不同,操作的对象也不同

C:\Users\XIFENFEI>sqlplus / as sysdba

SQL*Plus: Release 11.2.0.1.0 Production on 星期日 11月 20 20:39:06 20

Copyright (c) 1982, 2010, Oracle.  All rights reserved.


连接到:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Productio
With the Partitioning, Oracle Label Security, OLAP, Data Mining,
Oracle Database Vault and Real Application Testing options

SQL> create user xffa identified by xifenfei;

用户已创建。

SQL> grant connect,resource to xffa;

授权成功。

SQL> create user xffb identified by xifenfei;

用户已创建。

SQL> grant connect,resource to xffb;

授权成功。

SQL> conn xffa/xifenfei
已连接。
xffa>create table tmp(str varchar2(50));

表已创建。

xffa>insert into tmp values
  2  ('my name is xffa');

已创建 1 行。

xffa>commit;

提交完成。

xffa>create or replace procedure definer_proc as
  2      begin
  3        for x in (select sys_context('userenv', 'current_user') current_user,

  4                         sys_context('userenv', 'session_user') session_user,

  5                         sys_context('userenv', 'current_schema') current_sch
ema,
  6                         str
  7                    from tmp) loop
  8        dbms_output.put_line('Current User:   ' || x.current_user);
  9        dbms_output.put_line('Session User:   ' || x.session_user);
 10        dbms_output.put_line('Current Schema: ' || x.current_schema);
 11        dbms_output.put_line('Tables Value:    ' || x.str);
 12      end loop;
 13    end;
 14    /

过程已创建。

xffa>create or replace procedure invoker_proc AUTHID CURRENT_USER as
  2      begin
  3        for x in (select sys_context('userenv', 'current_user') current_user,

  4                         sys_context('userenv', 'session_user') session_user,

  5                         sys_context('userenv', 'current_schema') current_sch
ema,
  6                         str
  7                    from tmp) loop
  8        dbms_output.put_line('Current User:   ' || x.current_user);
  9        dbms_output.put_line('Session User:   ' || x.session_user);
 10        dbms_output.put_line('Current Schema: ' || x.current_schema);
 11        dbms_output.put_line('Tables Value:    ' || x.str);
 12      end loop;
 13    end;
 14    /

过程已创建。

xffa>grant execute on definer_proc to xffb;

授权成功。

xffa>grant execute on invoker_proc to xffb;

授权成功。

xffa>set serveroutput on
xffa>exec definer_proc;
Current User:   XFFA
Session User:   XFFA
Current Schema: XFFA
Tables Value:    my name is xffa

PL/SQL 过程已成功完成。

xffa>exec invoker_proc;
Current User:   XFFA
Session User:   XFFA
Current Schema: XFFA
Tables Value:    my name is xffa

PL/SQL 过程已成功完成。

xffa>conn xffb/xifenfei
已连接。
xffb>exec xffa.definer_proc;

PL/SQL 过程已成功完成。

xffb>set serveroutput on
xffb>exec xffa.definer_proc;
Current User:   XFFA
Session User:   XFFB
Current Schema: XFFA
Tables Value:    my name is xffa

PL/SQL 过程已成功完成。
--除了session是当前用户的,其他都是这个过程所属用户

xffb>exec xffa.invoker_proc;
BEGIN xffa.invoker_proc; END;

*
第 1 行出现错误:
ORA-00942: 表或视图不存在
ORA-06512: 在 "XFFA.INVOKER_PROC", line 3
ORA-06512: 在 line 1
--根据这个提示,很容易知道是tmp表不存在,也就是说明这个没有调用xffa.tmp表

xffb>create table tmp(str varchar2(50));

表已创建。

xffb>insert into tmp values
  2  ('my name is xffb');

已创建 1 行。

xffb>commit;

提交完成。

xffb>exec xffa.invoker_proc;
Current User:   XFFB
Session User:   XFFB
Current Schema: XFFB
Tables Value:    my name is xffb

PL/SQL 过程已成功完成。
--这个可以看出当时调用者的时候,执行的完全是当前用户下面的对象

在定义者(definer)权限下,执行的用户操作的schema为定义者,所操作的对象是定义者在编译时指定的对象。
在调用者(invoker)权限下,执行的用户操作的schema为当前用户,所操作的对象是当前模式下的对象。

二、执行的权限不同

xffb>create or replace procedure createtbl_definer as
  2      begin
  3        execute immediate 'create table xff_definer (id number)';
  4      end;
  5      /

过程已创建。

xffb>create or replace procedure createtbl_invoker AUTHID CURRENT_USER  as
  2      begin
  3        execute immediate 'create table xff_invoker (id number)';
  4      end;
  5      /

xffb>grant execute on createtbl_definer to xffa;

授权成功。

xffb>grant execute on createtbl_invoker to xffa;

授权成功。

xffb>exec createtbl_definer;
BEGIN createtbl_definer; END;

*
第 1 行出现错误:
ORA-01031: 权限不足
ORA-06512: 在 "XFFB.CREATETBL_DEFINER", line 3
ORA-06512: 在 line 1
--提示权限不足,很明显是缺少创建表的权限

xffb>exec createtbl_invoker;

PL/SQL 过程已成功完成。

xffb>desc xff_invoker;
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------

 ID                                                 NUMBER
--调用者创建成功

xffb>conn xffa/xifenfei
已连接。
xffa>exec xffb.createtbl_definer;
BEGIN xffb.createtbl_definer; END;

*
第 1 行出现错误:
ORA-01031: 权限不足
ORA-06512: 在 "XFFB.CREATETBL_DEFINER", line 3
ORA-06512: 在 line 1
--定义者同样提示没有权限创建表,通过1中的试验,我们知道
--定义者执行的这个过程定义者的对象,也就是说,是因为xffb无权创建表导致该提示

xffa>exec xffb.createtbl_invoker;

PL/SQL 过程已成功完成。

xffa>desc xff_invoker;
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------

 ID                                                 NUMBER

xffa>conn / as sysdba
已连接。
SQL>select owner,table_name from dba_tables where table_name=upper('xff_invoker');

OWNER                          TABLE_NAME
------------------------------ ------------------------------
XFFB                           XFF_INVOKER
XFFA                           XFF_INVOKER
--xffa用户执行成功,并且在自己的schema下面创建了表,证明了1的正确

SQL>GRANT CREATE TABLE TO XFFB;

授权成功。

SQL>conn xffb/xifenfei
已连接。
xffb>exec createtbl_definer;

PL/SQL 过程已成功完成。

xffb>desc xff_definer;
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------

 ID                                                 NUMBER
--说明直接授权是的定义者操作成功,但是角色(resource)不能使其操作成功

xffb>conn xffa/xifenfei
已连接。
xffa>exec xffb.createtbl_definer;
BEGIN xffb.createtbl_definer; END;

*
第 1 行出现错误:
ORA-00955: 名称已由现有对象使用
ORA-06512: 在 "XFFB.CREATETBL_DEFINER", line 3
ORA-06512: 在 line 1
--因为定义者执行的是过程创建者的对象,因为XFFB.CREATETBL_DEFINER已经创建成功

在定义者(definer)权限下,当前用户的权限为角色无效情况下所拥有的权限。
在调用者(invoker)权限下,当前用户的权限为当前所拥有的权限(含角色)。

三、执行的效率不同
在定义者(definer)权限下,过程被静态编译静态执行(相对而言),所执行sql语句在共享区池中是可被共享使用的
在调用者(invoker)权限下,过程静态编译,但动态执行,虽然执行的语句相同,但不同用户执行,其sql语句在共享池中并不能共享。

参考:http://www.itpub.net/thread-935634-1-1.html

此条目发表在 Oracle 分类目录。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>