动态构建DBMS_CLOUD.CREATE_EXTERNAL_TABLE执行报标识符未声明问题
问题原因
出现该报错是Oracle权限机制的特性导致:
默认创建的是定义者权限存储过程,这类存储过程在编译和执行时,仅识别直接授予用户的显式权限,所有通过角色间接授予的权限都会被忽略。你直接在新会话执行动态SQL能成功,说明当前用户所属角色已经拥有DBMS_CLOUD包的执行权限,但该权限在存储过程内部不会生效。
解决方案
可以任选以下两种方式的一种解决:
方式1:显式授予DBMS_CLOUD执行权限
使用DBA权限用户(如SYS、Oracle自治数据库的ADMIN用户)执行以下授权语句,直接给TEST用户授予包执行权限:
GRANT EXECUTE ON SYS.DBMS_CLOUD TO TEST;
额外需确认的配套权限:
- 你当前已拥有
CREATE TABLE权限,满足创建外部表的基础要求 - 确认你对TEST用户的默认表空间有使用配额,避免创建表时出现空间权限报错
- 确认你拥有凭证
TEST_OBJ_STORE的访问权限
方式2:修改存储过程为调用者权限
在存储过程定义时添加AUTHID CURRENT_USER参数,指定存储过程以调用者的会话权限执行,此时角色授予的权限会生效,无需单独给用户授包权限:
create or replace procedure test AUTHID CURRENT_USER -- 新增调用者权限声明 AS l_cloud_statement clob; L_error_msg varchar2(4000); -- 剩余原有代码保持不变
如果执行时报包名不存在的错误,可在动态SQL中使用包的全限定名SYS.DBMS_CLOUD替代DBMS_CLOUD,或者给当前用户创建同义词:
CREATE SYNONYM DBMS_CLOUD FOR SYS.DBMS_CLOUD;
代码小修正
你提供的存储过程异常捕获部分存在变量名笔误:定义的错误信息变量是L_error_msg,但调用log_error存储过程时传入的是未定义的GP_error_msg,需修正避免异常捕获逻辑失效。
内容的提问来源于stack exchange,提问作者B-Rad
相关产品推荐
相关产品推荐

