exec从程序中收集表统计信息

时间:2013-01-31 11:28:26

标签: oracle

如果我创建了一个程序:

CREATE OR REPLACE PROCEDURE SchameB.PRC_GATHER_STATS IS
BEGIN
    SYS.DBMS_STATS.GATHER_TABLE_STATS( 'SchName', 'TableName', CASCADE => TRUE);
END;

并执行它;

EXEC SchameB.PRC_GATHER_STATS;

这给了我错误ORA-20000: Unable to analyze TABLE "SchameA"."TableName", insufficient privileges or does not exist。但这有效:

EXEC SYS.DBMS_STATS.GATHER_TABLE_STATS( 'SchameA', 'TableName', CASCADE => TRUE);

EXEC过程和表的用户使用不同的模式。

为什么我在通过程序执行此操作时出错?

2 个答案:

答案 0 :(得分:9)

要收集另一个架构中对象的统计信息,您需要ANALYZE ANY系统权限。我似乎运行您的过程的用户具有该权限,但通过角色授予。正如the documentation says

  

在任何已命名的PL / SQL块中禁用所有角色(存储过程,   使用定义者权利执行的函数或触发器。

您可以GRANT ANALYZE ANY直接发送给您的用户,也可以创建程序with invoker's rights,如下:

CREATE OR REPLACE PROCEDURE SchameB.PRC_GATHER_STATS
AUTHID CURRENT_USER IS
BEGIN
    SYS.DBMS_STATS.GATHER_TABLE_STATS('SchName', 'TableName', CASCADE => TRUE);
END;
/

直接EXEC DBMS_STATS过程时,它作为匿名块运行,并且始终以调用者的权利运行 - 尊重角色。

答案 1 :(得分:3)

如果您希望某个程序能够由没有ANALYSE ANY角色的用户运行,那么您可以将AUTHID设置为DEFINER

CREATE OR REPLACE PROCEDURE SchameB.PRC_GATHER_STATS
AUTHID DEFINER IS
BEGIN
    SYS.DBMS_STATS.GATHER_TABLE_STATS('SchName', 'TableName', CASCADE => TRUE);
END;