当我有一个类似的 sql 语句select * from table1
时,它工作得很好,但是一旦我把它放入一个函数中,我得到:
ORA-00942: table or view does not exist
如何解决这个问题?
很有可能从 table1 中选择的权限已授予角色,并且该角色已授予您。授予角色的特权对用户编写的 PL/SQL 不可用,即使用户已被授予角色。
对于已被授予 sys 拥有的对象的 dba 角色的用户,您会经常看到这种情况。具有 dba 角色的用户将能够,例如SELECT * from V$SESSION
,但不能编写包含SELECT * FROM V$SESSION
.
解决方法是直接向用户授予对相关对象的显式权限,例如,在上述情况下,SYS 用户必须GRANT SELECT ON V_$SESSION TO MyUser;
您可以查看几件事。根据您的问题,函数所有者似乎与表所有者不同。
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
确保函数与表在同一个数据库模式中。
要么你没有对该模式/表的权限,要么表确实存在。如果您在存储过程中使用其他模式表,通常会发生此问题。例如。如果您从用户/模式 ABC 运行存储过程,并且在同一个 PL/SQL 中,则有来自用户/模式 XYZ 的表。在这种情况下,ABC 应该具有 GRANT 即 XYZ 表的权限
全部授予ABC;
Select * From Dba_Tab_Privs Where Owner = 'XYZ'and Table_Name = <Table_Name>;
一个非常简单的解决方案是使用您的表名添加数据库名称,如果您的数据库名称是DBMS
并且表是,info
那么它将DBMS.info
用于任何查询。
如果您的查询是
select * from STUDENTREC where ROLL_NO=1;
它可能会显示错误,但
select * from DBMS.STUDENTREC where ROLL_NO=1;
不是因为现在实际上找到了您的表。