无法从包内创建表

pn9klfpd  于 2022-09-18  发布在  Java
关注(0)|答案(2)|浏览(75)

我正在尝试创建一个包,并使用CTAS查询在其中放置和创建表。此表需要频繁刷新,并始终从基础数据中添加/删除列。由于表的结构不断变化,要在每次刷新时更新合并/更新查询以说明新的/缺失的列,这将是相当麻烦的。目前,我有执行简单删除和创建的外部脚本,但我需要将其集中在数据库中;因此,我正在尝试创建一个包来执行此操作;然而,我在权限方面遇到了问题。

作为概念证明,以下代码在作为匿名块运行时可以工作:

create table my_test_table as select * from dual; --create test table

declare
v_count int;
begin
   select count(*) into v_count from all_tab_columns where table_name = upper('my_test_table');
   if v_count >= 1 then
      execute immediate 'drop table my_test_table';
   end if;

execute immediate q'[
create table my_test_table as
select * from dual
]';
end;

select * from my_test_table; -- shows expected results

但当创建一个包来做同样的事情时;

CREATE OR REPLACE PACKAGE test_pkg AS

  PROCEDURE test_procedure;

END test_pkg;

CREATE OR REPLACE package body test_pkg as

procedure test_procedure
is
    v_count int;

begin
        select count(*) into v_count from all_tab_columns where table_name = upper('my_test_table');
        if v_count >= 1 then
            execute immediate 'drop table my_test_table';
        end if;

        execute immediate q'[
        create table my_test_table as
        select * from dual
        ]';

end test_procedure;

end test_pkg;
/

并使用以下代码进行测试:

create table my_test_table as select * from dual; --make sure table exists

execute TEST_PKG.TEST_PROCEDURE; --results in errors

select * from my_test_table; --table does not exist; therefore, DROP statement works but not CREATE

我得到以下错误(与执行TEST_PKG.TEST_PROCEDURE有关):

ORA-01031: insufficient privileges
ORA-06512: at test_pkg, line 15

在执行包之后测试测试表的存在时,我可以看到它不再存在。这意味着DROP语句正在工作,但CREATE TABLE语句导致权限不足错误。

从包中创建表所需的权限的任何洞察都将非常有帮助。

9wbgstp7

9wbgstp71#

仅当您具有“CREATE TABLE”或“CREATE ANY TABLE”权限但直接授予用户(由角色授予不起作用)时,才允许在过程中创建表。

Https://docs.oracle.com/cd/B19306_01/network.102/b14266/authoriz.htm#i1008334
PL/SQL块和角色

PL/SQL块中角色的使用取决于它是匿名块还是命名块(存储过程、函数或触发器),以及它是以定义者权限还是以调用者权限执行。

具有定义者权限的命名块

在以定义者权限执行的任何命名的PL/SQL块(存储过程、函数或触发器)中,所有角色都被禁用。角色不用于权限检查,并且您不能在定义者的权限过程中设置角色。

要检查直接授予您的用户(而不是按角色)的系统权限,您可以从您的用户运行以下查询:

SELECT * FROM USER_SYS_PRIVS;
68de4m5k

68de4m5k2#

在没有AUTHID CURRENT_USER子句的情况下,您创建的包是一个定义者权利包。它只能执行直接授予程序包定义者的特权所允许的操作。“直接”是这里的关键点--通过启用的角色授予的特权在包执行期间不会得到尊重。

您可能已经为您的用户启用了RESOURCE或类似的角色,这就解释了为什么您可以在测试期间创建表,而不是通过包过程。

尝试将CREATE TABLEUNLIMITED TABLESPACE系统权限直接授予您的用户,然后重新创建包。(如果可行,请将UNLIMITED TABLESPACE替换为数据库中相应表空间上的配额)。

相关问题