我有一个名称空间XXX
,我创建了一些表和一些存储过程......
他们有一个名称空间YYY
,他们在那里创建了一些表......
他们授予XXX
访问他们的表的权限,所以当我使用XXX
连接与SQL Developer连接时,我可以这样做:
SELECT * FROM YYY.TableA
但是如果我尝试从存储过程(简单存储过程或包)中运行那个相同的语句,则存储过程不会编译。它发生在很多sp上。我还有其他许可吗?我正在运行这样的:
CREATE OR REPLACE PROCEDURE PRC_SOMESP(
) AS BEGIN
END PRC_SOMESP;
不能访问YYY表的程序编译得很好。
提前致谢。
在Justin Cave回应之后,我正在尝试将“AUTHID CURRENT_USER”句子添加到sp中,但得到相同的“表或视图不存在”结果:
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
我应该检查其他什么吗?
答案 0 :(得分:11)
最有可能的问题是,拨款是通过角色完成的。授权人权限存储过程(默认值)中不提供授予用户的权限。
在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表的调用者权限存储过程。
答案 1 :(得分:0)
如果您从XXX
架构访问表,则在架构YYY
上的存储过程中,请确保您完全符合它们的条件:
select count(1) from YYY.TableA;
要考虑的其他事项是套管(如果您在Oracle标识符中混合使用大写和小写)。
最后一件事:发布你得到的错误。用这种方式帮助你会更容易。
答案 2 :(得分:0)
我刚遇到同样的问题。我不是DBA,但向我解释的方式是#34;基本的是你的个人角色权限在存储过程中没有效果。"
我被建议用表的所有者限定SP的名称,如下所示:
CREATE OR REPLACE PROCEDURE yyy.PRC_PROC1( PARAMETERS... ) etc
这在我的开发环境中适用于我的情况。我的环境只有一个命名空间,所以我不确定这会解决OP的问题,但希望能帮助将这个问题推向下一个查找这个问题的18K人; - )。
此外,当我将我的SP投入生产时,我将需要删除限定符,我们的安装软件将在适当的权限下运行。