调用者权限过程的权限问题

首先描述一下当时我碰到的问题:我写了一个存储过程,要在其中使用DBMS_METADATA过程获取另一个用户的某对象的定义。[@more@]SQL> CREATE OR REPLACE PROCEDURE P_TEST AS
2 BEGIN
3 FOR I IN (SELECT DBMS_METADATA.GET_DDL('TABLE', 'DUAL', 'SYS') DEFINE FROM DUAL) LOOP
4 DBMS_OUTPUT.PUT_LINE(SUBSTR(I.DEFINE, 1, 255));
5 END LOOP;
6 END;
7 /
过程已创建。
SQL> SET SERVEROUT ON SIZE 1000000
SQL> EXEC P_TEST
BEGIN P_TEST; END;
*
ERROR 位于第 1 行:
ORA-31603: 对象 "DUAL" 属于类型 TABLE, 在方案 "SYS" 中未找到
ORA-06512: 在"SYS.DBMS_SYS_ERROR", line 105
ORA-06512: 在"SYS.DBMS_METADATA", line 628
ORA-06512: 在"SYS.DBMS_METADATA", line 1221
ORA-06512: 在line 1
ORA-06512: 在"YANGTK.P_TEST", line 3
ORA-06512: 在line 1
过程在编译是没有报错,而在执行时报错。但是,如果单独执行上面的SQL是没有问题的:
SQL> SELECT DBMS_METADATA.GET_DDL('TABLE', 'DUAL', 'SYS') FROM DUAL;
DBMS_METADATA.GET_DDL('TABLE','DUAL','SYS')
-------------------------------------------------------------------------
CREATE TABLE "SYS"."DUAL"
( "DUMMY" VARCHAR2(1)
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 32768 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "SYSTEM"
当时认为,直接在SQL中可以运行,而在存储过程中不能运行,说明是角色的问题。存储过程中角色无效,导致了在执行DBMS_METADATA.GET_DDL过程时缺少权限。于是考虑使用调用者权限存储过程。因为调用者权限过程不会屏蔽角色:
SQL> CREATE OR REPLACE PROCEDURE P_TEST AUTHID CURRENT_USER AS
2 BEGIN
3 FOR I IN (SELECT DBMS_METADATA.GET_DDL('TABLE', 'DUAL', 'SYS') DEFINE FROM DUAL) LOOP
4 DBMS_OUTPUT.PUT_LINE(SUBSTR(I.DEFINE, 1, 255));
5 END LOOP;
6 END;
7 /
过程已创建。
SQL> EXEC P_TEST
CREATE TABLE "SYS"."DUAL"
( "DUMMY" VARCHAR2(1)
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS LOGGING
STORAGE(INITIAL 32768 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0
FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL
PL/SQL 过程已成功完成。
再次运行过程,这次执行成功。
一直就认为是角色导致的问题,而没有继续深究。而这次仔细看了Tom对定义者权限和调用者权限存储过程的描述才真正彻底清楚了导致上述现象的原因。
一个调用者权限的存储过程,如果在定义者权限存储过程中被调用,则它的行为表现将像一个定义者权限的过程。这时由于定义者权限过程中,CURRENT_SCHEMA和所拥有的权限都是固定的,调用者权限过程中所有可能发生变化的东西都被固定了下来。
而如果直接调用或者通过调用者权限过程来调用,那么这个调用者权限过程的全部特性得以保留。而这就是上面碰到的那个问题的真正答案。
DBMS_METADATA.GET_DDL本身是一个调用者权限过程:
SQL> SELECT OBJECT_NAME, PROCEDURE_NAME, AUTHID FROM DBA_PROCEDURES
2 WHERE OBJECT_NAME = 'DBMS_METADATA' AND PROCEDURE_NAME = 'GET_DDL';
OBJECT_NAME PROCEDURE_NAME AUTHID
------------------------------ ------------------------------ ------------
DBMS_METADATA GET_DDL CURRENT_USER
所以,当通过SQL直接调用或通过调用者权限存储过程调用时,Oracle运行没有问题,而通过定义者权限存储过程调用时,因为缺少了角色的权限而失败。

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

转载于:http://blog.itpub.net/60217/viewspace-1002940/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值