
需求:
1、想做个自动查找HW表的存储过程,定时查找高水位表并进行相应的回收。
实现:
1、写了个存储过程,分成两个游标循环,第一个循环查找表并执行HW的回收;
2、在存储过程中第二个循环查询由于第一步回收表导致表上的索引失效,执行重建索引。
问题:
存储过程编写完成后,执行时第一个游标循环执行了,第二个没有执行。见标记黄色的位置
create PROCEDURE Clean_HW_Table
as
S_SQL VARCHAR2(2000);
t_tablename varchar2(255);
t_index_name varchar2(2000);
CURSOR c1 IS SELECT
D.TABLE_NAME
FROM DBA_TABLES D
WHERE D.BLOCKS > 10
AND ROUND(D.NUM_ROWS / D.BLOCKS, 2) < 5
AND d.OWNER =(SELECT SYS_CONTEXT (‘USERENV’, ‘SESSION_USER’) ur FROM DUAL)
AND d.TABLE_NAME not like ‘VT%’;
BEGIN
BEGIN
FOR x IN c1
LOOP
t_tablename := x.TABLE_NAME;
S_SQL :=‘alter table ‘||t_tablename ||’ deallocate unused’;
EXECUTE IMMEDIATE S_SQL;
S_SQL :=‘alter table ‘||t_tablename ||’ move’;
EXECUTE IMMEDIATE S_SQL;
dbms_stats.gather_table_stats(‘EAS1’,t_tablename, estimate_percent => 100,cascade=>TRUE, method_opt => ‘FOR ALL COLUMNS SIZE AUTO’,degree =>6);
END LOOP;
END;
BEGIN
FOR LINE2 IN (SELECT owner, index_name
FROM dba_indexes
WHERE owner =(SELECT SYS_CONTEXT (‘USERENV’, ‘SESSION_USER’) ur FROM DUAL)
AND status NOT IN (‘VALID’, ‘N/A’)
ORDER BY owner, index_name
) LOOP
t_index_name:= ‘alter index ’ || LINE2.OWNER ||’.’|| LINE2.index_name || ’ rebuild online nologging’;
DBMS_OUTPUT.PUT_LINE (t_index_name);
EXECUTE IMMEDIATE t_index_name;
END LOOP;
END;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.PUT_LINE (‘NO_DATA_FOUND’);
RETURN;
WHEN OTHERS
THEN
DBMS_OUTPUT.PUT_LINE (‘OTHERS’);
RETURN;
END;
/