我正在尝试创建一个包,并使用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语句导致权限不足错误。
从包中创建表所需的权限的任何洞察都将非常有帮助。
2条答案
按热度按时间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块(存储过程、函数或触发器)中,所有角色都被禁用。角色不用于权限检查,并且您不能在定义者的权限过程中设置角色。
要检查直接授予您的用户(而不是按角色)的系统权限,您可以从您的用户运行以下查询:
68de4m5k2#
在没有
AUTHID CURRENT_USER
子句的情况下,您创建的包是一个定义者权利包。它只能执行直接授予程序包定义者的特权所允许的操作。“直接”是这里的关键点--通过启用的角色授予的特权在包执行期间不会得到尊重。您可能已经为您的用户启用了
RESOURCE
或类似的角色,这就解释了为什么您可以在测试期间创建表,而不是通过包过程。尝试将
CREATE TABLE
和UNLIMITED TABLESPACE
系统权限直接授予您的用户,然后重新创建包。(如果可行,请将UNLIMITED TABLESPACE
替换为数据库中相应表空间上的配额)。