6

如果我创建一个过程:

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在不同的模式中。

为什么通过程序执行此操作时会出现错误?

4

2 回答 2

9

要在另一个模式中收集对象的统计信息,您需要ANALYZE ANY系统权限。我似乎运行您的过程的用户具有该特权,但通过角色授予。正如文档所说

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

您可以GRANT ANALYZE ANY直接对您的用户,也可以创建具有调用者权限的过程,如下所示:

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

当您直接执行EXECDBMS_STATS过程时,它作为匿名块运行,并且始终以调用者的权限运行 - 尊重角色。

于 2013-01-31T12:03:09.873 回答
3

如果您希望该过程能够由没有ANALYSE ANY角色的用户运行,那么您可以AUTHIDDEFINER

CREATE OR REPLACE PROCEDURE SchameB.PRC_GATHER_STATS
AUTHID DEFINER IS
BEGIN
    SYS.DBMS_STATS.GATHER_TABLE_STATS('SchName', 'TableName', CASCADE => TRUE);
END;
于 2014-09-18T23:04:46.043 回答