从表游标重建索引

时间:2014-08-18 20:30:20

标签: oracle indexing

朋友......继续我的调试疯狂周...... 我有一个curTable部分在用户@Bob的帮助下工作...现在尝试此测试的下一阶段,并尝试在owner.table的时间重建所有索引,这些索引由rec1.curTable游标识别。

我花了一些时间再次坚持游标部分,有人可以帮助或指出我的错误吗?

CREATE OR REPLACE PROCEDURE moveTbl (OldTbs in varchar2, NewTbs in varchar2)
    AUTHID CURRENT USER
IS
  CURSOR curTable IS
    SELECT owner, table_name, tablespace_name
      FROM dba_tables
      WHERE tablespace_name = OldTbs
      ORDER BY TABLE_NAME;
rec1 curTable%ROWTYPE;

  CURSOR curIndex (TabOwn IN varchar2, TabNam IN VARCHAR2)
IS
  SELECT table_owner, table_name, owner, index_name, tablespace_name
  FROM dba_indexes
  WHERE table_owner = rec1.owner
  AND table_name = rec1.table_name;
rec2 CurIndex%ROWTYPE;

BEGIN
  FOR rec1 IN curTable LOOP
    dbms_output.putline(rec1.owner || '.' || rec1.table_name);

    EXECUTE IMMEDIATE 'alter table ' || rec1.owner || '.' || rec1.table_name ||
                      ' move tablespace ' || NewTbs;

   -- Starting curIndex
     OPEN curIndex (rec1.owner, rec1.table_name); LOOP
        BEGIN
          FETCH curIndex into rec2;
        EXIT when curIndex%NOTFOUND 

  dbms_output.PUT_LINE ('alter index '||rec2.owner||'.'rec2.index_name||' rebuild tablespace '|| NewTbs ||' online')
      END;

      END LOOP; -- index cursor loop
      CLOSE curIndex;   

END;
  END LOOP;  --curTable for loop
END moveTbl;

1 个答案:

答案 0 :(得分:1)

你还没有说过你面临的问题,但第二个游标的查询不对; rec1不在范围内。您应该使用游标参数:

CURSOR curIndex (TabOwn IN varchar2, TabNam IN VARCHAR2)
IS
  SELECT table_owner, table_name, owner, index_name, tablespace_name
  FROM dba_indexes
  WHERE table_owner = TabOwn
  AND table_name = TabNam;

您选择的光标synatx不需要来自行类型的rec1声明; rec2除非您将其更改为使用相同的循环类型。但是,您不需要内循环中的开始/结束。你似乎还有一个额外的end浮动。您可以简化一下:

BEGIN
  FOR rec1 IN curTable LOOP
    dbms_output.putline(rec1.owner || '.' || rec1.table_name);

    EXECUTE IMMEDIATE 'alter table ' || rec1.owner || '.' || rec1.table_name ||
                      ' move tablespace ' || NewTbs;

    FOR rec2 IN curIndex (rec1.owner, rec1.table_name) LOOP

      EXECUTE IMMEDIATE 'alter index '||rec2.owner||'.'rec2.index_name
        ||' rebuild tablespace '|| NewTbs ||' online';

    END LOOP; -- index cursor loop
  END LOOP; -- outer table loop
END moveTbl;

然后您也不需要声明rec2