首页 > 解决方案 > 动态构建 DBMS_CLOUD.CREATE_EXTERNAL_TABLE,立即执行不起作用

问题描述

当我尝试在存储过程或打包程序中使用 DBMS_CLOUD.CREATE_EXTERNAL_TABLE 动态构建表时,我遇到了一个问题。动态代码的 dbms_ouput.put_line 将生成正确的代码,我可以复制并在新会话中运行没问题,但不能在 PROC 或 PACKAGE 内。错误:开发 - ORA-06550:第 1 行,第 1 列:PLS-00201:必须声明标识符“DBMS_CLOUD”

select *
  from USER_SYS_PRIVS; 

username privilege              admin_option
TEST     CREATE RULE SET             NO
TEST     CREATE TABLE                NO
TEST     CREATE EVALUATION CONTEXT   NO
TEST     SELECT ANY DICTIONARY       NO
TEST     CREATE JOB                  NO
TEST    CREATE RULE NO

测试过程

create or replace procedure test
 AS
 
l_cloud_statement clob;
L_error_msg       varchar2(4000);


begin

        l_cloud_statement:= 'BEGIN'||CHR(13)||
                                                'DBMS_CLOUD.CREATE_EXTERNAL_TABLE('||CHR(13)||
                                                'table_name => ''TESTING_EXT_TAB'','||CHR(13)||
                                                'credential_name => ''TEST_OBJ_STORE'','||CHR(13)||
                                                'file_uri_list => ''https://objectstorage.eu-frankfurt-1.oraclecloud.com/n/rks6fos4/b/bucketuploads/o/testing_tab.csv'','||CHR(13)||
                                                'format => json_object(''delimiter'' value '','',''skipheaders'' value ''1''),'||CHR(13)||
                                                'column_list => ''col1  varchar2(200)'');'||chr(13)||                                        
                                                'END;';


dbms_output.put_line(l_cloud_statement);

execute IMMEDIATE l_cloud_statement;

exception
 WHEN OTHERS THEN
    L_error_msg := SQLERRM;
    TEST_SYSTEM.log_error(GP_error_msg,
                                'TEST',         -- program
                                'DEV',                              -- error type
                                '0001',                          -- error code
                                NULL,
                                NULL,
                                NULL,
                                NULL,
                                1);


end;

在新会话中执行时有效的输出代码

BEGIN

DBMS_CLOUD.CREATE_EXTERNAL_TABLE(
table_name => 'TESTING_EXT_TAB',
credential_name => 'TEST_OBJ_STORE',
file_uri_list =>
'https://objectstorage.eu-frankfurt-1.oraclecloud.com/n/rks6fos4/b/bucketuploads/o/testing_tab.csv',
format => json_object('delimiter' value ',','skipheaders' value '1'),
column_list => 'col1  varchar2(200)');
END;

知道我错过了什么或做错了什么吗?

标签: oracleplsqlexternal-tablesexecute-immediatedbms-output

解决方案


您可能遇到了定义者的权利与调用者的权利问题,需要添加AUTHID CURRENT_USER到过程声明中。

SQL 语句和匿名 PL/SQL 块默认以调用者权限运行,这意味着它们可以使用所有直接权限、系统权限和角色权限。PL/SQL 对象(例如过程)默认以定义者权限运行,这意味着它们不能使用角色权限。(我相信这是因为角色可以选择性地启用或禁用,所以当你编译一个程序时,你不能确定它运行时会启用哪些角色。)

如果DBMS_CLOUD仅通过角色授予您的用户,您将需要使用调用者的权限重新编译 PL/SQL 对象,如下所示:

create or replace procedure test authid current_user is
...

推荐阅读