0% found this document useful (0 votes)
17 views16 pages

Splitter Hint

Uploaded by

tumatimahesh1984
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views16 pages

Splitter Hint

Uploaded by

tumatimahesh1984
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 16

rem This is the table splitter package rem

rem Copyright Oracle Corporation 2007 rem


rem Created by Joern Bartels Version 1.0 15-oct-2007 rem
rem Updated by Joern Bartels Version 1.1 05-nov-2007 rem
rem Updated by Joern Bartels Version 1.2 19-nov-2007 rem
rem Updated by Joern Bartels Version 1.3 04-dec-2007 rem
rem Updated by Joern Bartels Version 1.4 19-dec-2007 rem
rem Updated by Joern Bartels Version 1.4.1 10-jan-2008 rem
rem Updated by Joern Bartels Version 1.5 15-jul-2008 rem
rem Updated by Joern Bartels Version 1.6 15-oct-2008 rem
rem Updated by Joern Bartels Version 1.7 15-Jun-2009 rem
rem Updated by Joern Bartels Version 1.71 19-Jun-2012 rem
rem Updated by Joern Bartels Version 1.7.2 21-Jun-2012 rem
rem Updated by Joern Bartels Version 1.7.3 27-Jun-2012 rem
rem Updated by Joern Bartels Version 1.7.4 12-Sep-2012 rem
rem Updated by Joern Bartels Version 2.0.0 12-Jan-2013 rem
rem Updated by Joern Bartels Version 2.0.1 12-Jun-2013 rem
rem Updated by Joern Bartels Version 3.0.1 16-Nov-2015 rem
rem rem
rem To call the package, use the following syntax: rem
rem exec table_splitter.ranges ('<table>', '<column>', <count>,['<dir>']); rem
rem You may use the special column "ROWID", to select rowid splitting rem
rem <dir> is the oracle directory object for the output files. rem
rem Partitioned tables are automatically splitted by partition. rem
rem rem
rem Test_level = 1 creates test file to check splitting rem

create or replace package table_splitter authid current_user is


procedure ranges ( tab_name in varchar2, col_name in varchar2, num_pack in
number, dir in varchar2 default null);
procedure set_log_level (lvl in number);
procedure set_test_level (lvl in number);
end;
/
show errors

create or replace package body table_splitter is

type range_arr is table of varchar2 (1000);


splitter_version varchar2(30) := '3.0.1';
test_level number := 0;
log_level number := 0;
log_file utl_file.file_type;
test_file utl_file.file_type;
user_error boolean := false;

use_dir varchar2 (30) := '~TABLE_SPLITTER_RANGES_DIR';

procedure check_directory (dir in varchar2) is


-- checks the existance of the output directory
cnt number;

begin
if dir is not null then
use_dir := dir;
end if;
select count (*)
into cnt
from all_directories
where directory_name = use_dir;
if cnt = 0 then
raise_application_error (-20010, 'The directory ' || use_dir || ' needs to be
created!');
end if;
end;

procedure delete_files (tab_name in varchar2, num_packages in number) is


-- Deletes files from previous runs.
begin
for i in 1..(num_packages + 100) loop
begin
UTL_FILE.FREMOVE(use_dir, translate (upper (tab_name), '/', '_') || '-' ||
i || '.WHR');
exception
when others then null;
end;
end loop;
end;

procedure set_log_level (lvl in number) is


begin
log_level := lvl;
end;

procedure set_test_level (lvl in number) is


begin
test_level := lvl;
end;

function check_test_level (tst in number) return boolean is


begin
return bitand (test_level, tst) = tst;
end;

procedure put_message (message in varchar2) is


begin
begin
utl_file.put_line (log_file, message);
exception
when others then null;
end;
dbms_output.put_line (message);
end;

procedure log_message (lvl in number, message in varchar2) is


begin
if lvl = 1000 then
put_message ('******** ERROR *************');
put_message (message);
put_message ('Splitting terminated');
utl_file.fclose (log_file);
elsif lvl <= log_level then
put_message (message);
end if;
end;

PROCEDURE Log_Errors ( i_buff in varchar2 ) IS


g_start_pos integer := 1;
g_end_pos integer;
FUNCTION Output_One_Line RETURN BOOLEAN IS
BEGIN
g_end_pos := Instr ( i_buff, Chr(10), g_start_pos );
IF g_end_pos > 0 THEN
log_message (0, Substr ( i_buff, g_start_pos, g_end_pos-g_start_pos ) );
g_start_pos := g_end_pos+1;
RETURN TRUE;
ELSE
log_message (0, Substr ( i_buff, g_start_pos, (Length(i_buff)-g_start_pos)
+1 ) );
RETURN FALSE;
END IF;
END Output_One_Line;
BEGIN
WHILE Output_One_Line() LOOP
NULL;
END LOOP;
END Log_Errors;

procedure raise_splitter_error (err_text in varchar2) is


begin
log_message (1000, err_text);
user_error := true;
raise_application_error (-20100, err_text);
end;

procedure create_hint (WHR_file in utl_file.file_type, tab_name in varchar2,


col_name in varchar2, split_type in varchar2) is
iname varchar2 (30);
col_pos number;
split_index boolean;
primary_index boolean;
begin
if split_type = 'ROWID' then
utl_file.put_line (WHR_file, '/*+ ROWID ("' || tab_name || '") */');
elsif split_type = 'CLUSTER' then
-- Check for Split Index
begin
split_index := false;
select index_name
into iname
from user_ind_columns
where table_name = tab_name and
index_name = tab_name || '~IMG' and
column_name = col_name and
column_position = 1;
split_index := true;
exception
when no_data_found then
null;
end;
if split_index then
utl_file.put_line (WHR_file, '/*+ INDEX ("' || tab_name || '", "' || iname
|| '") */');
else
-- Check for primary key containing the column
begin
primary_index := false;
select index_name, column_position
into iname, col_pos
from user_ind_columns
where table_name = tab_name
and column_name = col_name
and ( index_name = tab_name || '~0' or index_name like tab_name ||
'%_0');
primary_index := true;
exception
when no_data_found then
null;
end;
if primary_index then
if col_pos = 1 then
utl_file.put_line (WHR_file, '/*+ INDEX ("' || tab_name || '", "' ||
iname || '") */');
else
utl_file.put_line (WHR_file, '/*+ index_ss_asc ("' || tab_name || '",
"' || iname || '") */');
end if;
else
utl_file.put_line (WHR_file, '/*+ FULL ("' || tab_name || '") parallel
("' || tab_name || '", 4) */');
end if;
end if;
elsif split_type = 'PARTITION' then
utl_file.put_line (WHR_file, '/*+ FULL ("' || tab_name || '") */');
end if;
end;

procedure ins_ranges_rowid (tab_name in varchar2, start_rowid in rowid, end_rowid


in rowid, num_pack in number) is
WHR_file utl_file.file_type;
cond varchar2 (300);
begin
-- Open the WHR file

WHR_file := UTL_FILE.FOPEN(use_dir,
translate (upper (tab_name), '/', '_') || '-' ||
num_pack || '.WHR', 'W');

utl_file.put_line (WHR_file, 'tab: ' || tab_name);

if start_rowid is null then


cond:= 'WHERE (ROWID <= CHARTOROWID(''' || end_rowid || '''))';
elsif end_rowid is null then
cond:= 'WHERE (ROWID >= CHARTOROWID(''' || start_rowid || ''') )';
else
cond:= 'WHERE (ROWID >= CHARTOROWID(''' || start_rowid || ''') and ROWID
<= CHARTOROWID(''' || end_rowid || '''))';
end if;
utl_file.put_line (WHR_file, cond);

-- Output of Hint
create_hint (WHR_file, tab_name, 'ROWID', 'ROWID');

utl_file.put_line (WHR_file, ' ');

-- Close the WHR file

utl_file.fclose (WHR_file);

if check_test_level (1) then


if num_pack = 1 then
utl_file.put_line (test_file, 'union all');
utl_file.put_line (test_file, 'select /*+ parallel*/ sum (cnt) from');
utl_file.put_line (test_file, '(select /*+ parallel */ count (*) cnt from
"' || tab_name || '" ' || cond);
else
utl_file.put_line (test_file, 'union all');
utl_file.put_line (test_file, 'select /*+ parallel */ count (*) cnt from
"' || tab_name || '" ' || cond);
end if;
end if;

end;

procedure ins_ranges (range in range_arr,


tab_name in varchar2, col_name in varchar2,
low_range in varchar2, high_range in varchar2,
rec_len in number, tot_rec_len in number,
recs in number, tot_recs in number, num_pack in number,
tot_pack in number, split_type in varchar2) is
WHR_file utl_file.file_type;
-- inserts the ranges
begin
-- Open the WHR file

WHR_file := UTL_FILE.FOPEN(use_dir,
translate (upper (tab_name), '/', '_') || '-' ||
num_pack || '.WHR', 'W');
for i in range.first..range.last loop
if (range.exists(i) and range(i) is not null) then
utl_file.put_line (WHR_file, 'tab: ' || tab_name);
utl_file.put_line (WHR_file, range(i));
-- Output of Hint
create_hint (WHR_file, tab_name, col_name, split_type);

utl_file.put_line (WHR_file, ' ');


end if;
end loop;

-- Close the WHR file

utl_file.fclose (WHR_file);

end;

procedure ins_ranges (first_range in out boolean, last_range in boolean,


tab_name in varchar2, col_name in varchar2,
low_range in varchar2, high_range in varchar2,
rec_len in number, tot_rec_len in number,
recs in number, tot_recs in number, num_pack in number,
tot_pack in number, split_type in varchar2) is
-- calculates the ranges and inserts the information
range varchar2 (1000);
WHR_file utl_file.file_type;
iname varchar2 (30);
begin
-- Open the WHR file

WHR_file := UTL_FILE.FOPEN(use_dir,
translate (upper (tab_name), '/', '_') || '-' ||
num_pack || '.WHR', 'W');

if not last_range then


if first_range then
first_range := false;
range := 'WHERE ("' || col_name || '" < ''' || high_range || ''')';
else
if high_range = 'MAXVALUE' then -- MAXVALUE Partition
range := 'WHERE ("' || col_name || '" >= ''' || low_range || ''')';
else
range := 'WHERE ("' || col_name || '" >= ''' || low_range ||
''') AND ("' || col_name || '" < ''' || high_range || ''')';
end if;
end if;

else
if low_range != 'MAXVALUE' then
range := 'WHERE ("' || col_name || '" >= ''' || low_range || ''')';
end if;

end if;

if range is not null then


utl_file.put_line (WHR_file, 'tab: ' || tab_name);
utl_file.put_line (WHR_file, range);

create_hint (WHR_file, tab_name, col_name, split_type);

utl_file.put_line (WHR_file, ' ');


end if;

-- Close the WHR file

utl_file.fclose (WHR_file);

end;

function isUTF8Clean (str in varchar2)


-- This procedure checks if all characters in the input string are printible
ASCII characters.
return boolean is
begin
for i in 1..length (str) loop
if ascii (substr (str, i, 1)) not between 32 and 127 then
return false;
end if;
end loop;
return true;
end;

procedure ranges_pc ( tab_name in varchar2, col_name in varchar2, num_packages in


number) is
-- This procedure calculates the ranges on cluster and pool tables based on the
record length
type refcursor is ref cursor;
curs1 refcursor;
curs2 refcursor;
low_range varchar2 (100);
high_range varchar2 (100);
sum_cluster_rec_len number := 0;
tot_cluster_rec_len number;
tot_cluster_rec_len_o number;
num_recs number := 0;
first_record boolean := true;
first_range boolean := true;
type rectype IS RECORD (col_val varchar2 (100), pagelg number, cnt number);
type rectypearr is table of rectype;
rec rectypearr;
max_fetch number := 10000;
last_fetch boolean := false;
pack_no number := 0;

begin

open curs1 for 'select /*+ full(t) parallel(t) */


sum(pagelg)
from "' || tab_name || '" t';
fetch curs1 into tot_cluster_rec_len_o;
close curs1;

tot_cluster_rec_len := tot_cluster_rec_len_o / num_packages;

open curs2 for 'select /*+ full(t) parallel (t) */ "' || col_name || '", sum
(pagelg) pagelg, count (*) cnt
from "' || tab_name || '" t group by "' || col_name || '" order
by "' || col_name || '"';

loop

fetch curs2 bulk collect into rec limit max_fetch;


last_fetch := curs2%notfound;
exit when rec.last is null;
for i in rec.first .. rec.last loop
if first_record then
low_range := rec(i).col_val;
first_record := false;
end if;

sum_cluster_rec_len := sum_cluster_rec_len + rec(i).pagelg;


num_recs := num_recs + rec(i).cnt;
high_range := rec(i).col_val;

if sum_cluster_rec_len >= tot_cluster_rec_len and pack_no < num_packages -


1 then
pack_no := pack_no + 1;
ins_ranges (first_range, false,
tab_name, col_name,
low_range, high_range,
sum_cluster_rec_len, tot_cluster_rec_len,
num_recs, 0, pack_no, num_packages, 'CLUSTER');

tot_cluster_rec_len_o := tot_cluster_rec_len_o - sum_cluster_rec_len;


tot_cluster_rec_len := tot_cluster_rec_len_o / (num_packages - pack_no);
low_range := high_range;
sum_cluster_rec_len := 0;
num_recs := 0;

end if;

end loop;

exit when last_fetch;

end loop;

if low_range is not null then


pack_no := pack_no + 1;
ins_ranges (first_range, true,
tab_name, col_name,
low_range, high_range,
sum_cluster_rec_len, tot_cluster_rec_len,
num_recs, 0, pack_no, num_packages, 'CLUSTER');
end if;

close curs2;

end; /* end of ranges_pc */

procedure ranges_tp ( tab_name in varchar2, col_name in varchar2, num_packages in


number) is
-- This procedure calculates the ranges on transparent tables
type refcursor is ref cursor;
curs1 refcursor;
curs2 refcursor;
low_range varchar2 (100);
high_range varchar2 (100);
sum_recs number := 0;
tot_recs number;
tot_recs_o number;
first_record boolean := true;
first_range boolean := true;
type rectype IS RECORD (col_val varchar2 (100), cnt number);
type rectypearr is table of rectype;
rec rectypearr;
max_fetch number := 10000;
last_fetch boolean := false;
pack_no number := 0;

begin

open curs1 for 'select /*+ parallel(t) */


count(*)
from "' || tab_name || '" t';
fetch curs1 into tot_recs_o;
close curs1;

tot_recs := tot_recs_o / num_packages;

open curs2 for 'select /*+ full (t) parallel (t) */ "' || col_name || '", count
(*) cnt
from "' || tab_name || '" t group by "' || col_name || '" order
by "' || col_name || '"';

loop

fetch curs2 bulk collect into rec limit max_fetch;


last_fetch := curs2%notfound;
exit when rec.last is null;
for i in rec.first .. rec.last loop
if first_record then
low_range := rec(i).col_val;
first_record := false;
end if;

sum_recs := sum_recs + rec(i).cnt;


high_range := rec(i).col_val;

if sum_recs > tot_recs and pack_no < num_packages - 1 and isUTF8Clean


(high_range) then

pack_no := pack_no + 1;
ins_ranges (first_range, false,
tab_name, col_name,
low_range, high_range,
0, 0,
sum_recs, tot_recs, pack_no, num_packages, 'TRANSPARENT');

tot_recs_o := tot_recs_o - sum_recs;


tot_recs := tot_recs_o / (num_packages - pack_no);
low_range := high_range;
sum_recs := 0;
end if;

end loop;

exit when last_fetch;

end loop;

if low_range is not null then


pack_no := pack_no + 1;
ins_ranges (first_range, true,
tab_name, col_name,
low_range, high_range,
0, 0,
sum_recs, tot_recs, pack_no, num_packages, 'TRANSPARENT');
end if;

close curs2;
end; /* end of ranges_tp */

procedure ranges_part ( tab_name in varchar2, num_packages in number) is


-- This procedure calculates the ranges on partitioned tables

type refcursor is ref cursor;


col_name varchar2 (30);
curs1 refcursor;
low_range varchar2 (100);
high_range varchar2 (100);
sum_recs number := 0;
tot_recs number;
tot_recs_o number := 0;
recs_part number := 0;
first_record boolean := true;
first_range boolean := true;
max_fetch number := 10000;
last_fetch boolean := false;
pack_no number := 0;
last_part_high_value varchar2 (30) := null;
type parttype IS RECORD (high_value varchar2 (30), cnt number);
type parttypearr is table of parttype;
parts parttypearr;

begin

select column_name
into col_name
from USER_PART_KEY_COLUMNS
where name = tab_name
and object_type = 'TABLE';

parts := parttypearr();

for rec in (select partition_name, high_value, partition_position


from user_tab_partitions
where table_name = tab_name
order by partition_position) loop

open curs1 for 'select count(*)


from "' || tab_name || '" partition ("' ||
rec.partition_name || '")';
fetch curs1 into recs_part;
close curs1;

parts.extend (1);
parts (rec.partition_position).cnt := recs_part;
if substr (rec.high_value, 1, 1) = '''' then
parts (rec.partition_position).high_value := ltrim (rtrim (rec.high_value,
''''), '''');
else
parts (rec.partition_position).high_value := rec.high_value;
end if;

tot_recs_o := tot_recs_o + recs_part;


last_part_high_value := rec.high_value;

end loop;
tot_recs := tot_recs_o / num_packages;

for i in parts.first .. parts.last loop


if first_record then
low_range := parts(i).high_value;
first_record := false;
end if;

sum_recs := sum_recs + parts(i).cnt;


high_range := parts(i).high_value;

if sum_recs > tot_recs and pack_no < num_packages - 1 then

pack_no := pack_no + 1;
ins_ranges (first_range, false,
tab_name, col_name,
low_range, high_range,
0, 0,
sum_recs, tot_recs, pack_no, num_packages, 'PARTITION');

tot_recs_o := tot_recs_o - sum_recs;


tot_recs := tot_recs_o / (num_packages - pack_no);
low_range := high_range;
sum_recs := 0;
end if;

end loop;

if low_range is not null and sum_recs > 0 then


pack_no := pack_no + 1;
ins_ranges (first_range, true,
tab_name, col_name,
low_range, high_range,
0, 0,
sum_recs, tot_recs, pack_no, num_packages, 'PARTITION');
end if;

end; /* end of ranges_part */

procedure ranges_rowid ( tab_name in varchar2, num_packages in number, tot_blocks


in number) is
-- This procedure calculates the ranges on rowids

type exttype is record (relative_fno number, block_id number, blocks


number);
type exttypearr is table of exttype;
extents exttypearr;
obj_id number;
num_blocks number; -- Blocks per Package
sum_blocks number; -- Running total
start_rowid rowid := null;
end_rowid rowid;
pack_no number := 0;
num_ext number := 0;

cursor sel_ext is
select /*+ OPT_PARAM ( '_optimizer_extended_stats_usage_control' 252) */
relative_fno, block_id, blocks
from sys.dba_extents
where owner = user
and segment_name = tab_name
order by relative_fno, block_id;
begin

-- get obj_id for rowid construction

select data_object_id
into obj_id
from user_objects
where object_type = 'TABLE'
and object_name = tab_name;

log_message (0, 'Size in blocks: ' || tot_blocks);

-- collect the extents.

open sel_ext;

-- calculate size of each package

num_blocks := trunc (tot_blocks / (num_packages + 0.1));


sum_blocks := 0;

-- loop over all extents

loop

fetch sel_ext bulk collect into extents limit 100000;

exit when extents.count = 0;

num_ext := num_ext + extents.count;

for i in extents.first..extents.last loop


sum_blocks := sum_blocks + extents (i).blocks;
end_rowid := dbms_rowid.rowid_create (1, obj_id, extents(i).relative_fno,
extents (i).block_id + extents
(i).blocks - 1, 999999);

if sum_blocks > num_blocks and not pack_no + 1 = num_packages then

pack_no := pack_no + 1;
end_rowid := dbms_rowid.rowid_create (1, obj_id, extents(i).relative_fno,

extents (i).block_id + extents


(i).blocks - 1, 999999);

log_message (1, 'Writing Package ' || pack_no || ' blocks: ' ||


sum_blocks);
log_message (1, 'Range: ' || start_rowid || ' - ' || end_rowid);

ins_ranges_rowid (tab_name, start_rowid, end_rowid, pack_no);

start_rowid := dbms_rowid.rowid_create (1, obj_id,


extents(i).relative_fno,
extents (i).block_id + extents
(i).blocks, 0);
sum_blocks := 0;
end if;
end loop;

exit when sel_ext%notfound;

end loop;
if sum_blocks > 0 then
pack_no := pack_no + 1;

log_message (1, 'Writing last Package ' || pack_no || ' blocks: ' ||
sum_blocks);
log_message (1, 'Range: ' || start_rowid || ' - ' );
ins_ranges_rowid (tab_name, start_rowid, null, pack_no);
end if;

close sel_ext;
log_message (0, 'Identified ' || num_ext || ' extents and wrote ' || pack_no ||
' Packages.');

end; /* end of ranges_rowid2 */

procedure ranges ( tab_name in varchar2, col_name in varchar2, num_pack in


number, dir in varchar2 default null) is

pagelg_cnt number;
part_cnt number;
cnt number;
-- delete following line for 9.2
start_CPU_time number := dbms_utility.get_cpu_time;
start_time number := dbms_utility.get_time;
num_rows number;
avg_row_len number;
bytes number;
blocks number;

begin

user_error := false;

-- Check Output directory

check_directory (dir);

-- Initialize logging

log_file := UTL_FILE.FOPEN(use_dir,
translate (upper (tab_name), '/', '_') || '.log',
'W');
log_message (0, 'Oracle table splitter Version: ' || splitter_version ||
' at ' || to_char (SYSDATE, 'yyyy.mm.dd hh24:mi:ss'));
log_message (0, 'Connected to:');
for banner_rec in (select banner from v$version) loop
log_message (0, banner_rec.banner);
end loop;
log_message (0, 'Splitting table: ' || tab_name);
log_message (0, 'Using Test Level: ' || test_level);

-- Initialize test file

if check_test_level (1) then


test_file := UTL_FILE.FOPEN(use_dir,
translate (upper (tab_name), '/', '_') ||
'_test.sql', 'W');
utl_file.put_line (test_file, 'select /*+ parallel */ count (*) from "' ||
tab_name || '"');
end if;

-- Check Table Parameter

begin
select num_rows, avg_row_len
into num_rows, avg_row_len
from user_tables
where table_name = tab_name;
exception
when no_data_found then
raise_splitter_error ('Invalid Table Name: ' || tab_name);
end;

-- Initialize test file

if check_test_level (1) then


test_file := UTL_FILE.FOPEN(use_dir,
translate (upper (tab_name), '/', '_') ||
'_test.sql', 'W');
utl_file.put_line (test_file, 'select /*+ parallel */ count (*) from "' ||
tab_name || '"');
end if;

select sum (bytes), sum (blocks)


into bytes, blocks
from user_segments
where segment_name = tab_name;

log_message (0, 'Rows: ' || num_rows || ' Size: ' || round (bytes/1024/1024) ||
' MB');
-- Check if the table is a clustered table

SELECT count (*)


into pagelg_cnt
FROM DDNTT
WHERE TABFORM = 'T'
AND TABTYPE = 'C'
AND TABNAME = tab_name;

if pagelg_cnt = 1 and col_name = 'ROWID' then


raise_splitter_error ('It is not possible, to split cluster tables by
ROWID!');
end if;
if pagelg_cnt = 1 and col_name = 'PAGENO' then
raise_splitter_error ('It is not possible, to split cluster tables by
PAGENO!');
end if;
if (tab_name like 'D010%' or tab_name like 'D02%' or tab_name like 'DDNTF%')
and col_name = 'ROWID' then
raise_splitter_error ('It is not possible, to split table ' || tab_name || '
by ROWID!');
end if;

-- Check if the table has a supported partitioning type

select count (*)


into part_cnt
from user_part_tables
where table_name = tab_name
and partitioning_type = 'RANGE'
and PARTITIONING_KEY_COUNT = 1;

-- Check if the column name is valid

if part_cnt = 0 and col_name != 'ROWID' then

select count (*)


into cnt
from user_tab_columns
where table_name = tab_name
and column_name = col_name;

if cnt = 0 then
raise_splitter_error ('Column name ' || col_name || ' invalid');
end if;

end if;

-- Cleanup the WRH files

delete_files (tab_name, num_pack);

-- Call the correct procedure

if pagelg_cnt = 1 then -- The table has a pagelg column - We split by


recordsize!
log_message (0, 'Splitting cluster table ' || tab_name || ' by column ' ||
col_name);
log_message (0, 'in ' || num_pack || ' packages.');
ranges_pc (tab_name, col_name, num_pack);
elsif part_cnt > 0 then -- Partitioned - We use Partition Split
log_message (0, 'Splitting partitioned table ' || tab_name || ' by partition
key ');
log_message (0, 'in ' || num_pack || ' packages.');
ranges_part (tab_name, num_pack);
elsif col_name = 'ROWID' then -- Rowid Split
log_message (0, 'Splitting transparent table ' || tab_name || ' by ROWID ');
log_message (0, 'in ' || num_pack || ' packages.');
ranges_rowid (tab_name, num_pack, blocks);
else
-- Not partitioned - We use standard splitter
log_message (0, 'Splitting transparent table ' || tab_name || ' by column '
|| col_name);
log_message (0, 'in ' || num_pack || ' packages.');
ranges_tp (tab_name, col_name, num_pack);

end if;
commit;

log_message (0, 'Splitting of table ' || tab_name || ' successfully completed,


needed ' ||
(dbms_utility.get_cpu_time - start_CPU_time) * 10 || ' msecs
CPU time, ' ||
(dbms_utility.get_time - start_time) * 10 || ' msecs elapsed
time.');
utl_file.fclose (log_file);
if check_test_level (1) then
utl_file.put_line (test_file, ');');
utl_file.fclose (test_file);
end if;

EXCEPTION
WHEN OTHERS THEN

if not user_error then


Log_Errors ( 'Error_Stack...' || Chr(10) ||
DBMS_UTILITY.FORMAT_ERROR_STACK() );
Log_Errors ( 'Error_Backtrace...' || Chr(10) ||
DBMS_UTILITY.FORMAT_ERROR_BACKTRACE() );
log_message (1000, 'Fatal error - See preceding lines');
else
user_error := false;
end if;
raise;
end;

end;
/

show errors

You might also like