从存储过程内部oracle“表或视图不存在”

时间:2010-11-16 19:18:56

标签: oracle stored-procedures

这种情况就是这样......

我有一个名称空间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  

我应该检查其他什么吗?

3 个答案:

答案 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投入生产时,我将需要删除限定符,我们的安装软件将在适当的权限下运行。