甲骨文:我的 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游戏广告性能指标