朋友......继续我的调试疯狂周...... 我有一个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;
答案 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
。