ORA-00942: 表或视图不存在(在单独的SQL中有效,但在Oracle函数中无效)

35

当我有一个 SQL 语句,如 select * from table1,它工作得很好,但是一旦我把它放到函数中,我就会得到:

ORA-00942: table or view does not exist 

如何解决这个问题?


也许该函数属于与表不同的模式? - Daniel Hilgarth
5个回答

54

很有可能你被授予了一个角色,该角色拥有从table1中选择数据的权限。但是,即使用户被授予了该角色,通过用户编写的PL/SQL代码是无法获得所授予的角色权限的。

在sys拥有的对象上,经常会看到被授予dba角色的用户。具有dba角色的用户可以执行像SELECT * from V$SESSION这样的操作,但是无法编写包含SELECT * FROM V$SESSION的函数。

解决方法是直接向用户授予涉及的对象明确的权限。例如,在上面的情况下,SYS用户必须执行GRANT SELECT ON V_$SESSION TO MyUser;


你能否使用该技术提供一个完整的PROCEDURE示例来更新这个答案? - user3554664
不幸的是,我现在没有从事使用Oracle的工作,所以我没有机器来测试我写的任何语法的有效性。但如果有其他人想尝试一下,那就请便了。 - Steve Broberg

22

有几个方面你可以考虑。根据你的问题,看起来函数所有者不同于表所有者。

1) 通过角色授权:为了在其他用户的对象上创建存储过程和函数,您需要直接访问这些对象(而不是通过角色访问)。

2) 

默认情况下,存储过程和 SQL 方法使用其所有者的权限而不是当前用户的权限执行。

如果你在 Schema A 中创建了一张表,在 Schema B 中创建了一个函数,则应该查看Oracle的Invoker/Definer Rights概念,以了解可能导致该问题的原因。

http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14261/subprograms.htm#LNPLS00809


5

请确保函数与表在同一个数据库模式中。


如果函数位于包内,则该包也需要属于与表相同的模式吗? - Victor
是的,必须这样做。否则,它将无法找到表。除非您在选择中包括模式名称:select columns from schema.table1 - Adriano Carneiro

2

您可能没有访问该模式/表的权限,或者该表不存在。如果您在存储过程中使用其他模式表,则通常会出现此问题。

例如,如果您从用户/模式ABC运行存储过程,并且在同一PL / SQL中有来自用户/模式XYZ的表,则ABC应该具有XYZ表的授权即权限。

授予 ABC 的所有权限:

Grant All On To ABC;

Select * From Dba_Tab_Privs Where Owner = 'XYZ'and Table_Name = <Table_Name>;

0
非常简单的解决方案是将数据库名称与表名一起添加,例如如果您的数据库名称为DBMS,表名为info,那么查询时应该使用DBMS.info
如果您的查询语句为:
select * from STUDENTREC where ROLL_NO=1;

它可能会显示一个错误,但是。
select * from DBMS.STUDENTREC where ROLL_NO=1; 

它不会,因为现在实际上已经找到了您的表格。

我曾经遇到过同样的问题,如果你不知道模式,可以尝试这里的第三个选项:https://www.techonthenet.com/oracle/errors/ora00942.php,对于这个例子,它应该是:SELECT owner FROM all_objects WHERE object_type IN ('TABLE','VIEW') AND object_name = 'STUDENTREC'; - chepyle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接