问题回忆:
为了在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
变量中,并由该过程的一部分可视化:
在同一SPACEMAN用户下完成的dbms_output.put_line('v_sql_str = '||v_sql_str);
就像魔术一样。 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
特权是不够的。确实帮了我的是link,由@Wernfried Domscheit提供。尊重,伙计!
程序创建为
CREATE OR REPLACE
PACKAGE spaceman.tmp_itcm4052 authid CURRENT_USER is
像咒语一样工作。