本文介绍了oracle“表或视图不存在";从内部存储过程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

场景是这样的...

我有一个命名空间XXX,在其中创建了一些表和一些存储过程...

I HAVE a namespace XXX where I created some tables and some stored procedures...

他们有一个命名空间YYY,他们在其中创建了一些表...

THEY HAVE a namespace YYY where they created some tables...

他们授予了XXX访问他们的表的权限,因此当我使用XXX连接连接到SQL Developer时,我可以这样做:

THEY GRANTED XXX access to their tables, so when I conect to SQL Developer using XXX connection, I can do:

SELECT * FROM YYY.TableA

但是,如果我尝试从存储过程(简单存储过程或程序包)内部运行相同的语句,则该存储过程不会编译.它发生在很多sp上.我还需要寻求其他许可吗???我正在像这样运行sp:

But if I try to run that very same statement from inside a stored procedure (either simple stored procedure or a package), the stored procedure does not compile. It happens to a lot of sp's. Is there any other permission that I have to ask for??? I'm running sp's like this:

CREATE OR REPLACE PROCEDURE PRC_SOMESP(
) AS BEGIN
END PRC_SOMESP;

不访问YYY表的过程可以很好地编译.

Procedures that does not access YYY tables do compile well.

先谢谢了.

贾斯汀·凯夫(Justin Cave)响应后,我试图在sp上添加"AUTHID CURRENT_USER"语句,但得到相同的表或视图不存在"结果:

After Justin Cave response, I'm trying to add "AUTHID CURRENT_USER" sentence to the sp's but getting the same "table or view does not exist" result:

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

我还应该检查其他东西吗?

Should I check anything else???

推荐答案

最有可能的问题是,授予是通过角色完成的.授予用户的特权在定义者的权限存储过程(默认)中不可用.

Most likely, the problem is that the grant was done via a role. Privileges granted to a user are not available in a definer's rights stored procedure (the default).

在SQL Developer中,相对容易地验证这是问题所在.如果运行命令

In SQL Developer, it is relatively easy to verify that this is the problem. If you run the command

SET ROLE none

然后运行SELECT语句,我希望您会收到相同的ORA-00942错误.

and then run the SELECT statement, I would expect that you would get the same ORA-00942 error.

假设是这种情况,通常的解决方案是要求YYY模式中表的所有者直接向您授予对表的访问权限,而不是通过角色来授予访问权限.除此以外,您可以通过在声明中添加AUTHID CURRENT_USER来将存储过程定义为调用者的权限存储过程.那将使过程的调用者需要访问基础对象,但是它将允许您的过程利用通过角色授予的特权.

Assuming that is the case, the solution would generally be to ask that the owners of the tables in the YYY schema to grant access to the tables directly to you rather than granting access via a role. Barring that, you could define your stored procedure as an invoker's rights stored procedure by adding AUTHID CURRENT_USER to the declaration. That would that the caller of the procedure would need to have access to the underlying objects but it would allow your procedures to make use of privileges granted through a role.

如果要创建调用者的权限存储过程,则还需要使用动态SQL引用表名,以将特权检查推迟到运行时.所以你会有类似的东西

If you want to create an invoker's rights stored procedure, you will also need to refer to the table name using dynamic SQL in order to defer the privilege check to runtime. So you would have something like

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表.

if you wanted an invoker's rights stored procedure that queried the TableA table in schema XXX.

这篇关于oracle“表或视图不存在";从内部存储过程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 18:25