来自存储过程内部的oracle "table or view does not exist"

标签 oracle stored-procedures

情况就是这样的...

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

相关文章:

c# - MySQL 存储过程 : Works manually & not with C#

database - 甲骨文硬解析

oracle - UniversalConnectionPoolManagerMBean 已注册

oracle - 在包编译中绕过 “table or view does not exist”

sql - 锁定 SQL Server 存储过程

java.lang.UnsupportedOperationException : org. hibernate.dialect.Oracle10gDialect 不支持通过存储过程的结果集

php - PHP中获取OCI-LOB的文本值

database - QSqlTableModel with QTableView - 考虑数据库定义的编辑约束

mysql - 如何在MySQL中从子存储过程返回更新的行数给父存储过程?

JAVA使用删除和插入语句调用存储过程