CREATE OR REPLACE PACKAGE BODY "XX_REBUILD_TABLE" AS
-- VERSION: 1.0
-- PURPOSE: REBUILD A SPECIFIED TABLE, ITS INDEXES, AND STATISTICS
-- HISTORY: 11-JUN-05 - VERSION 1.0 - IOC
g_row dba_tables%ROWTYPE;
g_extents NUMBER;
g_bytes NUMBER;
g_phase VARCHAR2(30);
--===================================================================================================
PROCEDURE rebuild_table(p_schema IN VARCHAR2, p_table IN VARCHAR2) IS
-- PURPOSE: MOVE THE TABLE
BEGIN
g_phase := 'rebuild_table';
fnd_file.put_line(fnd_file.output,'<LI>Moving '||p_schema||'.'||p_table);
EXECUTE IMMEDIATE 'ALTER TABLE '||p_schema||'.'||p_table||' MOVE';
fnd_file.put_line(fnd_file.output,'<LI><FONT COLOR="green">Done!</FONT>');
END rebuild_table;
--===================================================================================================
PROCEDURE rebuild_indexes(p_schema IN VARCHAR2, p_table IN VARCHAR2) IS
-- PURPOSE: REBUILD INDEXES FOR TABLE
BEGIN
g_phase := 'rebuild_indexes';
FOR i IN (SELECT owner, index_name FROM dba_indexes
WHERE table_owner = upper(p_schema)
AND table_name = upper(p_table)
AND status != 'VALID'
ORDER BY 1,2) LOOP
fnd_file.put_line(fnd_file.output,'<LI>Rebuilding Index '||i.owner||'.'||i.index_name);
BEGIN
EXECUTE IMMEDIATE 'ALTER INDEX '||i.owner||'.'||i.index_name||' REBUILD';
fnd_file.put_line(fnd_file.output,'<LI><FONT COLOR="green">Success!</FONT>');
EXCEPTION
WHEN OTHERS THEN
fnd_file.put_line(fnd_file.output,'<LI><FONT COLOR="red">'||sqlerrm||'</FONT>');
RAISE_APPLICATION_ERROR(-20001,sqlerrm);
END;
END LOOP;
END rebuild_indexes;
--===================================================================================================
PROCEDURE rebuild_statistics(p_schema IN VARCHAR2, p_table IN VARCHAR2) IS
-- PURPOSE: REGATHER STATS ON TABLE
l_row dba_tables%ROWTYPE;
l_num_rows NUMBER;
l_blocks NUMBER;
l_empty_blocks NUMBER;
l_avg_space NUMBER;
l_chain_cnt NUMBER;
l_avg_row_len NUMBER;
l_old_extents NUMBER;
l_old_bytes NUMBER;
l_new_extents NUMBER;
l_new_bytes NUMBER;
BEGIN
g_phase := 'rebuild_statistics';
-- REGATHER THE STATS
EXECUTE IMMEDIATE 'ANALYZE TABLE '||p_schema||'.'||p_table||' ESTIMATE STATISTICS';
-- GET THE AFTER PICTURE
SELECT * INTO l_row FROM dba_tables WHERE owner = upper(p_schema) AND table_name = UPPER(p_table);
SELECT count(*), SUM(bytes)/1024 INTO l_new_extents, l_new_bytes
FROM dba_extents
WHERE owner = UPPER(p_schema) AND segment_name = UPPER(p_table);
-- OUTPUT THE BEFORE/AFTER TABLE
fnd_file.put_line(fnd_file.output,'<H4>Statistics Comparison</H4><TABLE BORDER=1>
<TR><TH>Statistic</TH><TH>Before</TH><TH>After</TH></TR>');
fnd_file.put_line(fnd_file.output,'<TR><TD>Rows</TD><TD>'||g_row.num_rows||'</TD><TD>'||l_row.num_rows||'</TD></TR>');
fnd_file.put_line(fnd_file.output,'<TR><TD>Blocks</TD><TD>'||g_row.blocks||'</TD><TD>'||l_row.blocks||'</TD></TR>');
fnd_file.put_line(fnd_file.output,'<TR><TD>Empty Blocks</TD><TD>'||g_row.empty_blocks||'</TD><TD>'||l_row.empty_blocks||'</TD></TR>');
fnd_file.put_line(fnd_file.output,'<TR><TD>Avg Space</TD><TD>'||g_row.avg_space||'</TD><TD>'||l_row.avg_space||'</TD></TR>');
fnd_file.put_line(fnd_file.output,'<TR><TD>Chain Count</TD><TD>'||g_row.chain_cnt||'</TD><TD>'||l_row.chain_cnt||'</TD></TR>');
fnd_file.put_line(fnd_file.output,'<TR><TD>Avg Row Length</TD><TD>'||g_row.avg_row_len||'</TD><TD>'||l_row.avg_row_len||'</TD></TR>');
fnd_file.put_line(fnd_file.output,'<TR><TD>Extents</TD><TD>'||g_extents||'</TD><TD>'||l_new_extents||'</TD></TR>');
fnd_file.put_line(fnd_file.output,'<TR><TD>Total kBytes</TD><TD>'||g_bytes||'</TD><TD>'||l_new_bytes||'</TD></TR>');
fnd_file.put_line(fnd_file.output,'</TABLE>');
EXCEPTION
WHEN OTHERS THEN
fnd_file.put_line(fnd_file.output,'<FONT COLOR="red">Error Collecting Stats: '||sqlerrm||'</FONT>');
END rebuild_statistics;
--===================================================================================================
PROCEDURE rebuild(p_schema IN VARCHAR2,
p_table IN VARCHAR2) IS
-- PURPOSE: DRIVER PROGRAM
l_error BOOLEAN := FALSE;
BEGIN
g_phase := 'rebuild (non-CCR)';
fnd_file.put_line(fnd_file.output,'<HTML><HEAD><H3>Rebuilding Table '||p_schema||'.'||p_table||'</H3></HEAD>');
fnd_file.put_line(fnd_file.output,'<BODY><HR><UL>');
l_error := FALSE;
-- SAVE THE BEFORE IMAGE OF THE STATS
SELECT * INTO g_row FROM dba_tables WHERE owner = upper(p_schema) AND table_name = UPPER(p_table);
SELECT count(*), SUM(bytes)/1024 INTO g_extents, g_bytes
FROM dba_extents
WHERE owner = UPPER(p_schema) AND segment_name = UPPER(p_table);
-- MOVE THE TABLE
rebuild_table(p_schema, p_table);
-- REBUILD INDEXES
rebuild_indexes(p_schema, p_table);
fnd_file.put_line(fnd_file.output,'</UL>');
-- REGATHER STATS
rebuild_statistics(p_schema, p_table);
fnd_file.put_line(fnd_file.output,'</BODY></HTML>');
EXCEPTION
WHEN OTHERS THEN
fnd_file.put_line(fnd_file.output,
'<LI><FONT COLOR="red"> In '||g_phase||'Error: '||sqlerrm
||'</FONT></BODY></HTML>');
fnd_file.put_line(fnd_file.log,'In '||g_phase||'Error: '||sqlerrm);
RAISE_APPLICATION_ERROR(-20000,'Something Went Amiss! '||sqlerrm);
END rebuild;
--
--*****************************************************************************
--
PROCEDURE rebuild(errbuf OUT VARCHAR2, retcode OUT VARCHAR2,
p_schema IN VARCHAR2,
p_table IN VARCHAR2) IS
BEGIN
g_phase := 'rebuild (CCR)';
rebuild(p_schema, p_table);
END rebuild;
END;
/