存储过程不会从“all_”系统表返回记录

时间:2014-07-02 20:45:19

标签: sql oracle stored-procedures

我有一个存储过程需要遍历特定的系统表,以根据表索引字段执行某些逻辑。

当我的存储过程(存在于我自己的用户模式中)遍历all_ind_columns Oracle系统表时,不会返回任何记录。 当我的用户手动执行相同的select语句时,我可以看到所需的数据。

我发现如果在存储过程中使用dba_ind_columns,则会返回记录。

为什么直接从存储过程中访问时all_ind_columns为空?

CREATE OR REPLACE PROCEDURE SQLGEN 
       ( full_table IN VARCHAR2
         , action IN VARCHAR2
        , cols IN VARCHAR2
        , outtext OUT VARCHAR2 )
 AS 

voutput VARCHAR2(32767);
vallindexcolumns VARCHAR2(32767);

CURSOR cursor_index_columns IS
SELECT COLUMN_NAME,
       index_name,
       table_owner,
       TABLE_NAME,
       column_position
FROM all_ind_columns
WHERE index_name LIKE '%PRIMARY'
  AND TABLE_NAME = 'SAMPLE_TABLE_NAME'
ORDER BY column_position;

curr_record cursor_index_columns%ROWTYPE;

BEGIN
FOR curr_record IN cursor_index_columns LOOP 
    vallindexcolumns := 'Output for record now';
END LOOP;

outtext := vallindexcolumns;

END SQLGEN;

1 个答案:

答案 0 :(得分:2)

你似乎看到了两件事的融合。 all_*表仅显示您拥有权限的对象; definers-right's stored procedures中没有遵守通过角色授予的权限。

因此,如果您通过角色继承对表的权限,那么您可以在all_tables等中查看这些表,并在纯SQL中查询它们,并可以查询表本身;但默认情况下,您无法在存储过程中执行此操作。

您可以通过执行set role none并重新发出纯SQL查询来检查是否存在问题;它将不再返回任何东西。

您可以更改过程定义,以便尊重主叫用户的角色:

CREATE OR REPLACE PROCEDURE SQLGEN 
       ( full_table IN VARCHAR2
         , action IN VARCHAR2
        , cols IN VARCHAR2
        , outtext OUT VARCHAR2 )
AUTHID CURRENT_USER
AS
...

您对dba_*观看次数的权限必须直接授予您的用户,而不是通过角色;这些视图显示所有对象,而不仅仅是您拥有权限的对象。