动态构建 DBMS_CLOUD.CREATE_EXTERNAL_TABLE,立即执行不起作用

Posted

技术标签:

【中文标题】动态构建 DBMS_CLOUD.CREATE_EXTERNAL_TABLE,立即执行不起作用【英文标题】:Dynamically building DBMS_CLOUD.CREATE_EXTERNAL_TABLE, Execute Immediate doesn't work 【发布时间】:2021-10-25 16:36:42 【问题描述】:

当我尝试在存储过程或打包程序中使用 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;

知道我遗漏了什么或做错了什么吗?

【问题讨论】:

【参考方案1】:

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

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

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

create or replace procedure test authid current_user is
...

【讨论】:

感谢您的帮助。它通过将权限分配给我的用户来工作。

以上是关于动态构建 DBMS_CLOUD.CREATE_EXTERNAL_TABLE,立即执行不起作用的主要内容,如果未能解决你的问题,请参考以下文章

python动态构建类(类似声明)

Mybatis之动态构建SQL语句

动态构建中继查询

C# 构建动态树

使用 innerHTML 构建动态表

动态构建Lambda表达式实现EF动态查询