2
FOR r IN (select 'DRR_DEV.' ||object_name as obj from dba_objects where object_type = 'INDEX' 
and owner ='DRR_DEV')
  LOOP
        l_sql := 'ALTER INDEX '||r.obj||' REBUILD'||'';
        execute immediate l_sql;
  END LOOP; 

在 FOR..IN 循环之上,循环特定模式的所有索引并重建。我在循环开始和 ALTER 语句行几乎没有错误。

PL/SQL: SQL Statement ignored
PL/SQL: ORA-00942: table or view does not exist
PL/SQL: Statement ignored
PLS-00364: loop index variable 'R' use is invalid

我可以手动运行 select 语句,但不能通过 PLSQL 块,可能会出现什么问题?

4

1 回答 1

4

您似乎没有访问 DBA_OBJECTS 的权限。要么以 SYS 身份连接并运行这样的代码,要么向其他用户授予所需的权限,或者 - 甚至更好 - 以 DDR_DEV 身份连接。

啊,在 PL/SQL 之外它可以工作- 抱歉,之前没有注意到。事实是:通过角色获得的权限在 PL/SQL 中不起作用。因此,如果是这种情况,请将 SELECT ON DBA_OBJECTS 直接授予运行 PL/SQL 代码的用户。

我删除了限制 OWNER 的条件,因为 USER_OBJECTS 中没有这样的列。

这是在我的 SCOTT 用户上运行的示例:

SQL> CREATE TABLE test (id NUMBER);

Table created.

SQL> CREATE INDEX i1
  2     ON test (id);

Index created.

SQL> DECLARE
  2     l_sql   VARCHAR2 (100);
  3  BEGIN
  4     FOR r IN (SELECT object_name AS obj
  5                 FROM user_objects
  6                WHERE object_type = 'INDEX'             -- AND owner = 'DRR_DEV'
  7                                           )
  8     LOOP
  9        l_sql := 'ALTER INDEX ' || r.obj || ' REBUILD' || '';
 10        DBMS_OUTPUT.put_line (l_sql);
 11
 12        EXECUTE IMMEDIATE l_sql;
 13     END LOOP;
 14  END;
 15  /
ALTER INDEX I1 REBUILD

PL/SQL procedure successfully completed.

SQL>
于 2018-04-23T09:16:42.740 回答