Extract Schema Using DBMS_METADATA package

DBMS_METADATA is a powerful package provided in Oracle9i to extract the object definitions from the database.
It is possible to provide various setting before running this utility.
If the user does not want to output STORAGE along with DDL then run this procedure before

dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'STORAGE', false );

The following are then various options available

Object Type Name Datatype Meaning

All objects

PRETTY

BOOLEAN

If TRUE, format the output with indentation and line feeds. Defaults to TRUE
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'PRETTY', TRUE);

All objects

SQLTERMINATOR

BOOLEAN

If TRUE, append a SQL terminator (; or /) to each DDL statement. Defaults to FALSE.
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'SQLTERMINATOR', TRUE );

TABLE

SEGMENT_ATTRIBUTES

BOOLEAN

If TRUE, emit segment attributes (physical attributes, storage attributes, tablespace, logging). Defaults to TRUE.
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'SEGMENT_ATTRIBUTES', false );

TABLE

STORAGE

BOOLEAN

If TRUE, emit storage clause. (Ignored if SEGMENT_ATTRIBUTES is FALSE.) Defaults to TRUE.
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'STORAGE', false);

TABLE

TABLESPACE

BOOLEAN

If TRUE, emit tablespace. (Ignored if SEGMENT_ATTRIBUTES is FALSE.) Defaults to TRUE.
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'TABLESPACE', TRUE );

TABLE

CONSTRAINTS

BOOLEAN

If TRUE, emit all non-referential table constraints. Defaults to TRUE.
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'CONSTRAINTS', TRUE );

TABLE

REF_CONSTRAINTS

BOOLEAN

If TRUE, emit all referential constraints (foreign keys). Defaults to TRUE.
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'REF_CONSTRAINTS', TRUE );

TABLE

CONSTRAINTS_AS_ALTER

BOOLEAN

If TRUE, emit table constraints as separate ALTER TABLE (and, if necessary, CREATE INDEX) statements.
If FALSE, specify table constraints as part of the CREATE TABLE statement. Defaults to FALSE. Requires that CONSTRAINTS be TRUE.
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'CONSTRAINTS_AS_ALTER', TRUE );

TABLE

OID

BOOLEAN

If TRUE, emit the OID clause for object tables. Defaults to FALSE.
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'OID', false);

TABLE

SIZE_BYTE_KEYWORD

BOOLEAN

If TRUE, emit the BYTE keyword as part of the size specification of CHAR and VARCHAR2 columns that use byte semantics.
If FALSE, omit the keyword. Defaults to FALSE.
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'SIZE_BYTE_KEYWORD', false );

INDEX, CONSTRAINT, ROLLBACK_SEGMENT,
CLUSTER, TABLESPACE

SEGMENT_ATTRIBUTES

BOOLEAN

If TRUE, emit segment attributes (physical attributes, storage attributes, tablespace, logging). Defaults to TRUE.
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'SEGMENT_ATTRIBUTES', false );

INDEX, CONSTRAINT, ROLLBACK_SEGMENT,
CLUSTER

STORAGE

BOOLEAN

If TRUE, emit storage clause. (Ignored if SEGMENT_ATTRIBUTES is FALSE.) Defaults to TRUE.
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'STORAGE', false );

INDEX, CONSTRAINT, ROLLBACK_SEGMENT,
CLUSTER

TABLESPACE

BOOLEAN

If TRUE, emit tablespace. (Ignored if SEGMENT_ATTRIBUTES is FALSE.) Defaults to TRUE.
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'TABLESPACE', TRUE );

TYPE

SPECIFICATION

BOOLEAN

If TRUE, emit the type specification. Defaults to TRUE.
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'SPECIFICATION', TRUE );

TYPE

BODY

BOOLEAN

If TRUE, emit the type body. Defaults to TRUE.
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'BODY', TRUE );

TYPE

OID

BOOLEAN

If TRUE, emit the OID clause. Defaults to FALSE.
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'OID', TRUE );

PACKAGE

SPECIFICATION

BOOLEAN

If TRUE, emit the package specification. Defaults to TRUE.
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'SPECIFICATION', TRUE );

PACKAGE

BODY

BOOLEAN

If TRUE, emit the package body. Defaults to TRUE.
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'BODY', TRUE );

VIEW

FORCE

BOOLEAN

If TRUE, use the FORCE keyword in the CREATE VIEW statement. Defaults to TRUE.
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'FORCE', TRUE );

OUTLINE

INSERT

BOOLEAN

If TRUE, emit the INSERT statements into the OL$ dictionary tables that will create the outline and its hints.
If FALSE, emit a CREATE OUTLINE statement. Defaults to FALSE.
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'INSERT', TRUE );

Note: This object type is being deprecated.

All objects

DEFAULT

BOOLEAN

Calling SET_TRANSFORM_PARAM with this parameter set to TRUE has the effect of resetting all parameters for the transform to their default values.
Setting this FALSE has no effect. There is no default.
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'DEFAULT', false );

All objects

INHERIT

BOOLEAN

If TRUE, inherits session-level parameters. Defaults to FALSE. If an application calls ADD_TRANSFORM to add the DDL transform,
then by default the only transform parameters that apply are those explicitly set for that transform handle.
This has no effect if the transform handle is the session transform handle.
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'INHERIT', TRUE );

ROLE

REVOKE_FROM

Text

The name of a user from whom the role must be revoked. If this is a non-null string and if the CREATE ROLE statement grants you the role,
a REVOKE statement is emitted after the CREATE ROLE.
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'REVOKE_FROM', 'SCOTT' );

Note: When you issue a CREATE ROLE statement, Oracle may grant you the role. You can use this transform parameter to undo the grant.

Defaults to null string.

TABLESPACE

REUSE

BOOLEAN

If TRUE, include the REUSE parameter for datafiles in a tablespace to indicate that existing files can be reused.
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'REUSE', TRUE );

Defaults to FALSE.

CLUSTER, INDEX,
ROLLBACK_SEGMENT,
TABLE, TABLESPACE

PCTSPACE

NUMBER

A number representing the percentage by which space allocation for the object type is to be modified.
The value is the number of one-hundreths of the current allocation. For example, 100 means 100%.
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'PCTSPACE', 85);

If the object type is TABLESPACE, the following size values are affected:

- in file specifications, the value of SIZE

- MINIMUM EXTENT

- EXTENT MANAGEMENT LOCAL UNIFORM SIZE

For other object types, INITIAL and NEXT are affected.

The following PL/SQL code can be used to generate schema creation scripts

Only tables, indexes and constraints are included here


-- For setting the default transformation

BEGIN
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'PRETTY', TRUE );
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'CONSTRAINTS_AS_ALTER', true );
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'STORAGE', false );
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'SQLTERMINATOR', TRUE );
dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'SEGMENT_ATTRIBUTES', false ); 
END;
/

-- Output DATA to CLOB
-- Using sql*plus declare variable "schm" of type CLOB SQL> var schm clob SQL> declare a1 clob; prev_tab varchar2(40):=' '; str varchar2(32767); n1 number; begin DBMS_LOB.CREATETEMPORARY(:schm, true); for c1 in(select a.table_name , b.index_name from user_tables a, user_indexes b where a.table_name=b.table_name order by 1,2) LOOP if c1.table_name<>prev_tab THEN select dbms_metadata.get_ddl('TABLE', c1.table_name) INTO a1 from dual; DBMS_LOB.APPEND(:schm, a1); prev_tab := c1.table_name; END IF; select dbms_metadata.get_ddl('INDEX', c1.index_name) INTO a1 from dual; DBMS_LOB.APPEND(:schm, a1); END LOOP; END; / SQL> set long 500000 SQL> print :schm

It will be better to output the data to another table so that it can be queried later.


create table ddl_scripts(
object_name varchar2(50),
object_type varchar2(30),
text varchar2(4000));


--  Format the DDL text using trigger

create or replace trigger ddl_scripts_format_trg before insert on ddl_scripts
for each row
declare
n1 number;
n2 number;
BEGIN
n1 := instr(:new.text, '"."',1,1);
n2 := instr(:new.text, '"', 1,1);
if n1<50 then
:new.text := replace(substr(:new.text,1,n2-1)||substr(:new.text,n1+3), '"', null);
:new.text := ltrim(rtrim(:new.text, chr(10)), chr(10));
:new.text := ltrim(rtrim(:new.text, chr(32)), chr(32));
:new.text := ltrim(rtrim(:new.text, chr(10)), chr(10));
:new.text := ltrim(rtrim(:new.text, chr(32)), chr(32));
end if;
END;
/



declare
a1 varchar2(32767);
str varchar2(32767);
n1 number;
cur_user varchar2(30);
begin
select '"'||upper(username)||'"."' into cur_user from user_users;
for c1 in(select a.table_name from user_tables a where a.table_name 
not in(select object_name from user_recyclebin) order by 1)
LOOP
        select DBMS_LOB.SUBSTR(dbms_metadata.get_ddl('TABLE', c1.table_name), 32767,1) INTO a1 from dual;
        insert into ddl_scripts values(c1.table_name, 'TABLE', a1);
    for c2 in(select index_name from user_indexes where table_name=c1.table_name and index_type in('NORMAL', 'BITMAP') order by 1) 
    LOOP
        select DBMS_LOB.SUBSTR(dbms_metadata.get_ddl('INDEX', c2.index_name), 32767,1) INTO a1 from dual;
        insert into ddl_scripts values(c1.table_name, 'INDEX', a1);
    END LOOP;
END LOOP;

-- Trigger scripts
for c1 in(select table_name, trigger_name from user_triggers where trigger_name 
not in(select object_name from user_recyclebin) order by 1,2) LOOP
        select DBMS_LOB.SUBSTR(dbms_metadata.get_ddl('TRIGGER', c1.trigger_name), 32767,1) INTO a1 from dual;
        insert into ddl_scripts values(c1.table_name, 'TRIGGER', a1);
END LOOP;

-- Views
for c1 IN(select view_name from user_views order by 1) LOOP
        select DBMS_LOB.SUBSTR(dbms_metadata.get_ddl('VIEW', c1.view_name), 32767,1) INTO a1 from dual;
        insert into ddl_scripts values(c1.view_name, 'VIEW', a1);
END LOOP;

-- Sequence Scripts
for c1 IN(select sequence_name from user_sequences order by 1) LOOP
        select DBMS_LOB.SUBSTR(dbms_metadata.get_ddl('SEQUENCE', c1.sequence_name), 32767,1) INTO a1 from dual;
        insert into ddl_scripts values(c1.sequence_name, 'SEQUENCE', a1);
END LOOP;

-- Directoryies
for c1 in(select directory_name from all_directories order by 1) LOOP
        select DBMS_LOB.SUBSTR(dbms_metadata.get_ddl('DIRECTORY', c1.directory_name), 32767,1) INTO a1 from dual;
        insert into ddl_scripts values(c1.directory_name, 'DIRECTORY', a1);
END LOOP;

-- Materialized Views
for c1 in(select mview_name from user_mviews order by 1) LOOP
        select DBMS_LOB.SUBSTR(dbms_metadata.get_ddl('MATERIALIZED_VIEW', c1.mview_name), 32767,1) INTO a1 from dual;
        insert into ddl_scripts values(c1.mview_name, 'MATERIALIZED VIEW', a1);
END LOOP;

-- Materialized View Logs
for c1 in(select log_table from user_mview_logs order by 1) LOOP
        select DBMS_LOB.SUBSTR(dbms_metadata.get_ddl('MATERIALIZED_VIEW_LOG', c1.log_table), 32767,1) INTO a1 from dual;
        insert into ddl_scripts values(c1.log_table, 'MATERIALIZED_VIEW_LOG', a1);
END LOOP;

-- Synonyms
for c1 in(select synonym_name from user_synonyms order by 1) LOOP
        select DBMS_LOB.SUBSTR(dbms_metadata.get_ddl('SYNONYM', c1.synonym_name), 32767,1) INTO a1 from dual;
        insert into ddl_scripts values(c1.synonym_name, 'SYNONYM', a1);
END LOOP;

--  Types
for c1 in(select type_name from user_types order by 1) LOOP
        select DBMS_LOB.SUBSTR(dbms_metadata.get_ddl('TYPE', c1.type_name), 32767,1) INTO a1 from dual;
        insert into ddl_scripts values(c1.type_name, 'TYPE', a1);
END LOOP;
END;
/


-- Query the table ddl_scripts
SQL> set pagesize 0
SQL> set linesize 32767
SQL> set trimspool ON
SQL spool c:\temp\ddl.txt
SQL> select text from ddl_scripts order by 
     case when object_type in('TABLE', 'INDEX', 'TRIGGER') then 0 else 1 end, 
     object_name, decode(object_type, 'TABLE',1,'TRIGGER',3,'INDEX',2);

SQL> spool off

See Also

Manage Locks in Oracle
Scripts to generate schema objects
Using Index Fast Full Scan
Using Returning clause
Managing Tablespaces and Datafiles
Script to reorganize tables
Hidden Parameters in Oracle
Using Multiple block sizes for tablespaces
Index Optimization Scripts
Managing Constraints
Oracle Installation
Oracle Tips
Oracle links
Oracle Books
Indexing strategies
Segment usage statistics


Please Add Your Comments about this article
Your Name:
Email:
Subject:
Comments: