甲骨文:我的 DML 索引游戏拼图

Posted

技术标签:

【中文标题】甲骨文:我的 DML 索引游戏拼图【英文标题】:Oracle: my DML for Index recreation puzzle 【发布时间】:2019-11-18 15:21:16 【问题描述】:

问题回顾:

为了在 oracle 中自动创建 PVJOURNAL 表的索引,我在一个包中编写了一个过程。 表 PVJOURNAL 位于 PROVIEW 模式中。我的 SPACEMAN 用户在该架构中有足够的授权。下面是包的 DDL:

CREATE OR REPLACE 
PACKAGE spaceman.tmp_itcm4052 is

-- This proc rebuilds ALL indexes of a specific.
PROCEDURE         idx_rebuild;

END;
/

CREATE OR REPLACE 
PACKAGE BODY spaceman.tmp_itcm4052 is

--  ===========================================================================
PROCEDURE         idx_rebuild as
-- This proc rebuilds ALL indexes of a specific table. Run by Job
  v_sql_str     VARCHAR2(200);
begin

 FOR rec in (
             select owner ||'.'|| index_name as IDX_NAME,
                    tablespace_name          as TblSpace
               from sys.all_indexes
              where upper(index_type) = 'NORMAL'
                and upper(table_owner) = 'PROVIEW'
                and upper(table_name) in ('PVJOURNAL')
             )
 LOOP
     v_sql_str := 'ALTER INDEX '||rec.IDX_NAME||' rebuild tablespace '
                    ||rec.TblSpace||' online';
     -- ALTER INDEX ... SHRINK SPACE COMPACT
     -- ALTER INDEX ... DEALLOCATE UNUSED SHRINK SPACE COMPACT
     dbms_output.put_line('v_sql_str = '||v_sql_str);
     execute immediate v_sql_str;
     commit;
 END LOOP;
 end idx_rebuild;

END tmp_ITCM4052;
/

问题本身:

问题是我的 SPACEMAN 用户下的程序调用

begin
 spaceman.tmp_itcm4052.idx_rebuild;
end;

以错误结束

ORA-01031: 权限不足 - full view of the error

但是程序产生的直接运行的行保存到v_sql_str变量中,并由这段程序可视化: dbms_output.put_line('v_sql_str = '||v_sql_str);,在同一个 SPACEMAN 用户下完成,就像魔法一样。 proof that direct alter does work

问题:

我对pl/sql之神做错了什么?为什么对过程的调用失败而直接执行相同的命令 - 不是?

UPD:不仅GRANT INDEX ON PROVIEW.PVJOURNAL TO SPACEMAN; 没有帮助。此外,出于我还不知道的原因,将任何索引授予 SPACEMAN;也没有帮助。 用

仔细检查了它
SELECT PRIVILEGE
  FROM sys.dba_sys_privs
 WHERE upper(grantee) = 'SPACEMAN'
UNION
SELECT PRIVILEGE 
  FROM dba_role_privs rp JOIN role_sys_privs rsp ON (rp.granted_role = rsp.role)
 WHERE upper(rp.grantee) = 'SPACEMAN'
 ORDER BY 1;
特权ALTER ANY INDEX(以及ALTER ANY INDEXTYPE)在列表中。

UPD 1:事实证明,ALTER ANY INDEX 权限在这种情况下是不够的。对我有帮助的是@Wernfried Domscheit 提供的link。尊重,伙计!

过程创建为

CREATE OR REPLACE 
PACKAGE spaceman.tmp_itcm4052 authid CURRENT_USER is

就像一个咒语。

【问题讨论】:

您从哪个用户调用该过程? @Tejash - 过程调用和直接更改执行均在 spaceman 用户下完成。 spaceman.tmp_itcm4052 包也在 spaceman 的架构中。 【参考方案1】:

在 PL/SQL 块中,您只有直接授予用户的权限。由 ROLE(例如 DBA)授予的权限不适用于 PL/SQL 块(角色 PUBLIC 除外)。

CREATE ANY INDEX 直接授予用户,然后它应该可以工作。

上述行为是默认行为,称为“定义者权限单元”。您可以通过将AUTHID CURRENT_USER 添加到您的过程/包中来更改它。欲了解更多信息,请参阅Invoker's Rights and Definer's Rights (AUTHID Property)

注意在 DDL 语句之后不需要 COMMIT。 Oracle 执行隐式提交。

【讨论】:

感谢您的回答。我想知道是否可以将 alter 权限授予特定索引,而不是授予架构上的 任何索引 试试GRANT INDEX ON PROVIEW.PVJOURNAL TO SPACEMAN; 但我不知道它是否允许重建现有索引或只创建新索引。另请注意,此类索引可能在模式 SPACEMAN 而不是模式 PROVIEW 中定义。 @Wernifried Domischheit,不仅GRANT INDEX ON PROVIEW.PVJOURNAL TO SPACEMAN; 没有帮助。此外,由于我还不知道的原因,GRANT ALTER ANY INDEX to SPACEMAN; 也没有帮助。对主要帖子进行了更新...我现在迷路了...研究链接[Invoker's Rights and Definer's Rights (AUTHID Property)][1],由您之前提供... [1]: docs.oracle.com/database/121/LNPLS/subprograms.htm#LNPLS00809【参考方案2】:

当您调用直接 SQL 和在过程中使用它时,会使用不同的授权。

通过角色(例如 DBA)授予的权限不可用于 定义者的权限默认的存储过程。

只有直接授予用户的权限才能在 定义者权限存储过程。

您必须将ALTER ANY INDEX 权限直接授予您的用户。

干杯!!

【讨论】:

以上是关于甲骨文:我的 DML 索引游戏拼图的主要内容,如果未能解决你的问题,请参考以下文章

播客广告收入激增;腾讯云发布国内首个云原生智能数据湖产品图谱;Salesforce升级CDP;甲骨文宣布3D游戏广告性能指标

为啥当我的子查询无效时,此 SQL 查询会起作用? - 甲骨文 [重复]

水晶报告问题+甲骨文

甲骨文和 GitLab

他不执行该程序。第一步失败。甲骨文

001.数据库基础