/* CREATES SCRIPT TO RECREATE A TABLE-STRUCTURE INCL. STORAGE, CONSTRAINTS, TRIGGERS ETC. ------------------------------------------- This script creates scripts to recreate a table structure. Use the script to reorganise a table that has become fragmented, to get a definition that can be run on another database/schema or as a basis for altering the table structure (eg. drop a column!). IMPORTANT: Running the script is safe as it only creates two new scripts and does not do anything to your database! To get anything done you have to run the scripts created. The created scripts does the following: 1. save the content of the table 2. drop any foreign key constraints referencing the table 3. drop the table 4. creates the table with an Initial storage parameter that will accomodate the entire content of the table. The Next parameter is 25% of the initial. The storage parameters are picked from the following list: 64K, 128K, 256K, 512K, multiples of 1M. 5. create table and column comments 6. fill the table with the original content 7. create all the indexes incl storage parameters as above. 8. add primary, unique key and check constraints. 9. add foreign key constraints for the table and for referencing tables. 10.Create the table's triggers. 11.Compile any depending objects (cascading). 12.Grant table and column privileges. 13.Create synonyms. This script must be run as the owner of the table. If your table contains a LONG-column, use the COPY command in SQL*Plus to store/restore the data. USAGE ------ from SQL*Plus: start reorgtb This will create the scripts REORGS1.SQL and REORGS2.SQL REORGS1.SQL contains code to save the current content of the table. REORGS2.SQL contains code to rebuild the table structure. -------------------------------------------------------------- -------------------------------------------------------------- */ undef tab; accept tab char prompt 'Enter table name : ' set echo off set verify off column a1 new_val stor column b1 new_val nxt select decode(sign(1024-sum(bytes)/1024),-1, to_char((round(sum(bytes)/(1024*1024))+1))||'M', /* > 1M new rounded up to nearest Megabyte */ decode(sign(512-sum(bytes)/1024), -1,'1M', DECODE(SIGn(256-sum(bytes)/1024), -1,'512K', decode(sign(128-sum(bytes)/1024), -1,'256K', decode(sign(64-sum(bytes)/1024) , -1,'128K', '64K' ))))) a1, decode(sign(1024-sum(bytes)/4096),-1, to_char((round(sum(bytes)/(4096*1024))+1))||'M', /* > 1M new rounded up to nearest Megabyte */ decode(sign(512-sum(bytes)/4096), -1,'1M', decode(sign(256-sum(bytes)/4096), -1,'512K', decode(sign(128-sum(bytes)/4096), -1,'256K', decode(sign(64-sum(bytes)/4096) , -1,'128K', '64K' ))))) b1 from user_extents where segment_name=upper('&tab'); set pages 0 feed off verify off lines 150 col c1 format a132 spool reorgs1.sql PROMPT drop table bk_&&tab prompt / PROMPT create table bk_&&tab storage(initial &stor) as select * from &&tab prompt / PROMPT select count(*) from &&tab prompt / PROMPT select count(*) from bk_&&tab prompt / prompt pause prompt / spool off spool reorgs2.sql PROMPT spool reorgs2 select 'alter table '||table_name||' drop constraint '|| constraint_name||';' from user_constraints where r_constraint_name in (select constraint_name from user_constraints where table_name=upper('&&tab') and constraint_type in ('P','U')); prompt rem Pausing before drop of table &&tab...... prompt rem Please make sure the create of prompt rem the bk_&&tab has been created prompt rem in previous step prompt rem Press to continue prompt pause PROMPT drop table &&tab prompt / prompt create table &&tab select decode(column_id,1,'(',',') ||rpad(column_name,40) ||decode(data_type,'DATE' ,'DATE ' ,'LONG' ,'LONG ' ,'LONG RAW','LONG RAW ' ,'RAW' ,'RAW ' ,'CHAR' ,'CHAR ' ,'VARCHAR' ,'VARCHAR ' ,'VARCHAR2','VARCHAR2 ' ,'NUMBER' ,'NUMBER ' ,'unknown') ||rpad( decode(data_type,'DATE' ,null ,'LONG' ,null ,'LONG RAW',null ,'RAW' ,decode(data_length,null,null ,'('||data_length||')') ,'CHAR' ,decode(data_length,null,null ,'('||data_length||')') ,'VARCHAR' ,decode(data_length,null,null ,'('||data_length||')') ,'VARCHAR2',decode(data_length,null,null ,'('||data_length||')') ,'NUMBER' ,decode(data_precision,null,' ' ,'('||data_precision|| decode(data_scale,null,null ,','||data_scale)||')') ,'unknown'),8,' ') ||decode(nullable,'Y','NULL','NOT NULL') c1 from user_tab_columns where table_name = upper('&&tab') order by column_id / prompt ) select 'pctfree '||t.pct_free c1 ,'pctused '||t.pct_used c1 ,'initrans '||t.ini_trans c1 ,'maxtrans '||t.max_trans c1 ,'tablespace '||s.tablespace_name c1 ,'storage (initial '||'&stor' c1 ,' next '||'&stor' c1 ,' minextents '||t.min_extents c1 ,' maxextents '||t.max_extents c1 ,' pctincrease '||t.pct_increase||')' c1 from user_Segments s, user_tables t where s.segment_name = upper('&&tab') and t.table_name = upper('&&tab') and s.segment_type = 'TABLE' / prompt / select 'comment on table &&tab is '''||comments||''';' c1 from user_tab_comments where table_name=upper('&&tab'); select 'comment on column &&tab..'||column_name|| ' is '''||comments||''';' c1 from user_col_comments where table_name=upper('&&tab'); prompt insert into &&tab select * from bk_&&tab prompt / set serveroutput on declare cursor c1 is select index_name,decode(uniqueness,'UNIQUE','UNIQUE') unq from user_indexes ui where ui.table_name = upper('&&tab') and index_name not in ( select constraint_name from user_constraints uc where ui.table_name = uc.table_name); indname varchar2(50); cursor c2 is select decode(column_position,1,'(',',')||rpad(column_name,40) cl from user_ind_columns where table_name = upper('&&tab') and index_name = indname order by column_position; l1 varchar2(100); l2 varchar2(100); l3 varchar2(100); l4 varchar2(100); l5 varchar2(100); l6 varchar2(100); l7 varchar2(100); l8 varchar2(100); l9 varchar2(100); begin dbms_output.enable(100000); for c in c1 loop dbms_output.put_line('create '||c.unq||' index '||c.index_name ||' on &&tab'); indname := c.index_name; for q in c2 loop dbms_output.put_line(q.cl); end loop; dbms_output.put_line(')'); select 'pctfree '||i.pct_free , 'initrans '||i.ini_trans , 'maxtrans '||i.max_trans , 'tablespace '||i.tablespace_name , 'storage (initial '|| decode(sign(1024-sum(e.bytes)/1024),-1, to_char((round(sum(e.bytes)/(1024*1024))+1))||'M', decode(sign(512-sum(e.bytes)/1024), -1,'1M', decode(sign(256-sum(e.bytes)/1024), -1,'512K', decode(sign(128-sum(e.bytes)/1024), -1,'256K', decode(sign(64-sum(e.bytes)/1024) , -1,'128K', '64K'))))) , ' next '|| decode(sign(1024-sum(e.bytes)/4096),-1, to_char((round(sum(e.bytes)/(4096*1024))+1))||'M', decode(sign(512-sum(e.bytes)/4096), -1,'1M', decode(sign(256-sum(e.bytes)/4096), -1,'512K', decode(sign(128-sum(e.bytes)/4096), -1,'256K', decode(sign(64-sum(e.bytes)/4096) , -1,'128K', '64K'))))) , ' minextents '||s.min_extents , ' maxextents '||s.max_extents , ' pctincrease '||s.pct_increase||')' into l1,l2,l3,l4,l5,l6,l7,l8,l9 from user_extents e,user_segments s, user_indexes i where s.segment_name = c.index_name and s.segment_type = 'INDEX' and i.index_name = c.index_name and e.segment_name=s.segment_name group by s.min_extents,s.max_extents,s.pct_increase, i.pct_free,i.ini_trans,i.max_trans,i.tablespace_name ; dbms_output.put_line(l1); dbms_output.put_line(l2); dbms_output.put_line(l3); dbms_output.put_line(l4); dbms_output.put_line(l5); dbms_output.put_line(l6); dbms_output.put_line(l7); dbms_output.put_line(l8); dbms_output.put_line(l9); dbms_output.put_line('/'); end loop; end; / declare cursor c1 is select constraint_name, decode(constraint_type,'U',' UNIQUE',' PRIMARY KEY') typ, decode(status,'DISABLED','DISABLE',' ') status from user_constraints where table_name = upper('&&tab') and constraint_type in ('U','P'); cname varchar2(100); cursor c2 is select decode(position,1,'(',',')||rpad(column_name,40) coln from user_cons_columns where table_name = upper('&&tab') and constraint_name = cname order by position; l1 varchar2(100); l2 varchar2(100); l3 varchar2(100); l4 varchar2(100); l5 varchar2(100); l6 varchar2(100); l7 varchar2(100); l8 varchar2(100); l9 varchar2(100); begin for q1 in c1 loop cname := q1.constraint_name; dbms_output.put_line('alter table &&tab'); dbms_output.put_line('add constraint '||cname||q1.typ); for q2 in c2 loop dbms_output.put_line(q2.coln); end loop; dbms_output.put_line(')' ||q1.status); dbms_output.put_line('Using Index'); select 'pctfree '||i.pct_free , 'initrans '||i.ini_trans , 'maxtrans '||i.max_trans , 'tablespace '||i.tablespace_name , 'storage (initial '|| decode(sign(1024-sum(e.bytes)/1024),-1, to_char((round(sum(e.bytes)/(1024*1024))+1))||'M', decode(sign(512-sum(e.bytes)/1024), -1,'1M', decode(sign(256-sum(e.bytes)/1024), -1,'512K', decode(sign(128-sum(e.bytes)/1024), -1,'256K', decode(sign(64-sum(e.bytes)/1024) , -1,'128K', '64K'))))) , ' next '|| decode(sign(1024-sum(e.bytes)/4096),-1, to_char((round(sum(e.bytes)/(4096*1024))+1))||'M', decode(sign(512-sum(e.bytes)/4096), -1,'1M', decode(sign(256-sum(e.bytes)/4096), -1,'512K', decode(sign(128-sum(e.bytes)/4096), -1,'256K', decode(sign(64-sum(e.bytes)/4096) , -1,'128K', '64K'))))) , ' minextents '||s.min_extents , ' maxextents '||s.max_extents , ' pctincrease '||s.pct_increase||')' into l1,l2,l3,l4,l5,l6,l7,l8,l9 from user_extents e,user_segments s, user_indexes i where s.segment_name = cname and s.segment_type = 'INDEX' and i.index_name = cname and e.segment_name=s.segment_name group by s.min_extents,s.max_extents,s.pct_increase, i.pct_free,i.ini_trans,i.max_trans,i.tablespace_name ; dbms_output.put_line(l1); dbms_output.put_line(l2); dbms_output.put_line(l3); dbms_output.put_line(l4); dbms_output.put_line(l5); dbms_output.put_line(l6); dbms_output.put_line(l7); dbms_output.put_line(l8); dbms_output.put_line(l9); dbms_output.put_line('/'); end loop; end; / declare cursor c1 is select c.constraint_name,c.r_constraint_name cname2, c.table_name table1, r.table_name table2, decode(c.status,'DISABLED','DISABLE',' ') status, decode(c.delete_rule,'CASCADE',' on delete cascade ',' ') delete_rule from user_constraints c, user_constraints r where c.constraint_type='R' and c.r_constraint_name = r.constraint_name and c.table_name = upper('&&tab') union select c.constraint_name,c.r_constraint_name cname2, c.table_name table1, r.table_name table2, decode(c.status,'DISABLED','DISABLE',' ') status, decode(c.delete_rule,'CASCADE',' on delete cascade ',' ') delete_rule from user_constraints c, user_constraints r where c.constraint_type='R' and c.r_constraint_name = r.constraint_name and r.table_name = upper('&&tab'); cname varchar2(50); cname2 varchar2(50); cursor c2 is select decode(position,1,'(',',')||rpad(column_name,40) colname from user_cons_columns where constraint_name = cname order by position; cursor c3 is select decode(position,1,'(',',')||rpad(column_name,40) refcol from user_cons_columns where constraint_name = cname2 order by position; begin dbms_output.enable(100000); for q1 in c1 loop cname := q1.constraint_name; cname2 := q1.cname2; dbms_output.put_line('alter table '||q1.table1||' add constraint '); dbms_output.put_line(cname||' foreign key'); for q2 in c2 loop dbms_output.put_line(q2.colname); end loop; dbms_output.put_line(') references '||q1.table2); for q3 in c3 loop dbms_output.put_line(q3.refcol); end loop; dbms_output.put_line(') '||q1.delete_rule||q1.status); dbms_output.put_line('/'); end loop; end; / col c1 format a79 word_wrap set long 32000 set arraysize 1 select 'create or replace trigger ' c1, description c1, 'WHEN ('||when_clause||')' c1, trigger_body , '/' c1 from user_triggers where table_name = upper('&&tab') and when_clause is not null / select 'create or replace trigger ' c1, description c1, trigger_body , '/' c1 from user_triggers where table_name = upper('&&tab') and when_clause is null / select 'alter trigger '||trigger_name||decode(status,'DISABLED',' DISABLE',' ENABLE') from user_Triggers where table_name='&&tab'; set serveroutput on declare cursor c1 is select 'alter table '||'&&tab'||decode(substr(constraint_name,1,4),'SYS_',' ', ' add constraint ') a1, decode(substr(constraint_name,1,4),'SYS_','',constraint_name) ||' check (' a2, search_condition a3, ') '||decode(status,'DISABLED','DISABLE','') a4, '/' a5 from user_constraints where table_name = upper('&&tab') and constraint_type='C'; b1 varchar2(100); b2 varchar2(100); b3 varchar2(32000); b4 varchar2(100); b5 varchar2(100); fl number; begin open c1; loop fetch c1 into b1,b2,b3,b4,b5; exit when c1%NOTFOUND; select count(*) into fl from user_tab_columns where table_name = upper('&&tab') and upper(column_name)||' IS NOT NULL' = upper(b3); if fl = 0 then dbms_output.put_line(b1); dbms_output.put_line(b2); dbms_output.put_line(b3); dbms_output.put_line(b4); dbms_output.put_line(b5); end if; end loop; end; / create or replace procedure dumzxcvreorg_dep(nam varchar2,typ varchar2) as cursor cur is select type,decode(type,'PACKAGE BODY','PACKAGE',type) type1, name from user_dependencies where referenced_name=upper(nam) and referenced_type=upper(typ); begin dbms_output.enable(500000); for c in cur loop dbms_output.put_line('alter '||c.type1||' '||c.name||' compile;'); dumzxcvreorg_dep(c.name,c.type); end loop; end; / exec dumzxcvreorg_dep('&&tab','TABLE'); drop procedure dumzxcvreorg_Dep; select 'grant '||privilege||' on '||table_name||' to '||grantee|| decode(grantable,'YES',' with grant option;',';') from user_tab_privs where table_name = upper('&&tab'); select 'grant '||privilege||' ('||column_name||') on &&tab to '||grantee|| decode(grantable,'YES',' with grant option;',';') from user_col_privs where grantor=user and table_name=upper('&&tab') order by grantee, privilege; select 'drop synonym '||synonym_name||';' from user_synonyms where table_name=upper('&&tab'); select 'create synonym '||synonym_name||' for '||table_owner||'.'||table_name||';' from user_synonyms where table_name=upper('&&tab'); PROMPT REM PROMPT REM YOU MAY HAVE TO LOG ON AS SYSTEM TO BE PROMPT REM ABLE TO CREATE ANY OF THE PUBLIC SYNONYMS! PROMPT REM select 'drop public synonym '||synonym_name||';' from all_synonyms where owner='PUBLIC' and table_name=upper('&&tab') and table_owner=user; select 'create public synonym '||synonym_name||' for '||table_owner||'.'||table_name||';' from all_synonyms where owner='PUBLIC' and table_name=upper('&&tab') and table_owner=user; prompt spool off spool off set echo on feed on verify on /* --------------------------------------------------------- The scripts REORGS1.SQL and REORGS2.SQL have been created. Alter these script as necesarry. To recreate the table-structure, first run REORGS1.SQL. This script saves the content of your table in a table called bk_. If this script runs successfully run REORGS2.SQL. The result is spooled to REORGTB.LST. Check this file before dropping the bk_ table. --------------------------------------------------------- */