情况就是这样的...
我有一个命名空间XXX
,在其中创建了一些表和一些存储过程...
他们有一个命名空间YYY
,他们在其中创建了一些表...
他们授予了XXX
访问他们的表的权限,因此当我使用XXX
连接连接到SQL Developer时,我可以执行以下操作:
SELECT * FROM YYY.TableA
但是,如果我尝试从存储过程(简单存储过程或程序包)中运行相同的语句,则该存储过程将无法编译。它发生在很多sp上。我还需要寻求其他许可吗???我正在像这样运行sp:
CREATE OR REPLACE PROCEDURE PRC_SOMESP(
) AS BEGIN
END PRC_SOMESP;
不访问YYY表的过程可以很好地进行编译。
提前致谢。
在贾斯汀·凯文(Justin Cave)响应之后,我试图将“AUTHID CURRENT_USER”语句添加到sp上,但得到相同的“表或 View 不存在”结果:
CREATE OR REPLACE PROCEDURE PRC_PROC1( PARAMETERS... )
AUTHID CURRENT_USER
AS
MYVAR NUMBER;
BEGIN
STATEMENTS...
END PRC_PROC1;
CREATE OR REPLACE PACKAGE PKG_PROC2
AUTHID CURRENT_USER
AS
TYPE T_CURSOR IS REF CURSOR;
PROCEDURE PRC_PROC2( PARAMETERS... )
END PKG_PROC2
我还应该检查其他东西吗???
最佳答案
问题很可能是授予是通过角色完成的。授予用户的特权在定义者的权限存储过程(默认)中不可用。
在SQL Developer中,相对容易地验证这是问题所在。如果运行命令
SET ROLE none
然后运行SELECT语句,我希望您会收到相同的ORA-00942错误。
假设是这种情况,解决方案通常是要求YYY模式中表的所有者直接向您授予对表的访问权限,而不是通过角色来授予访问权限。除此以外,您可以通过在声明中添加AUTHID CURRENT_USER来将存储过程定义为调用者的权限存储过程。那将使过程的调用者需要访问基础对象,但是它将允许您的过程利用通过角色授予的特权。
如果要创建调用者的权限存储过程,则还需要使用动态SQL引用表名,以便将特权检查推迟到运行时。所以你会有类似的东西
CREATE OR REPLACE PROCEDURE PRC_SOMESP
AUTHID CURRENT_USER
AS
l_cnt pls_integer;
BEGIN
EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM yyy.TableA' INTO l_cnt;
END PRC_SOMESP;
如果您想要查询模式XXX中的TableA表的调用者权限存储过程。
关于来自存储过程内部的oracle "table or view does not exist",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4198052/