Script out Oracle DDL in an automated fashion
The reason you are having problems with dbms_metadata.get_ddl
is that it outputs CLOB
s which can be up to 4GB in size. By default, SQL*Plus and Oracle SQL Developer truncate long text so they don't trash the client with large gobs of text.
It's very easy to override this behavior in SQL*Plus with a few SET
commands and get clean DDL.
The script you need is:
-- Run this script in SQL*Plus.
-- don't print headers or other crap
set heading off;
set echo off;
set pagesize 0;
-- don't truncate the line output
-- trim the extra space from linesize when spooling
set long 99999;
set linesize 32767;
set trimspool on;
-- don't truncate this specific column's output
col object_ddl format A32000;
spool sys_ddl.sql;
SELECT dbms_metadata.get_ddl(object_type, object_name, owner) || ';' AS object_ddl
FROM DBA_OBJECTS
WHERE
OWNER = 'SYS'
AND OBJECT_TYPE IN (
'TABLE'
, 'INDEX'
, 'SEQUENCE'
, 'VIEW'
)
ORDER BY
OWNER
, OBJECT_TYPE
, OBJECT_NAME
;
spool off;
Well, if sqlplus is screwing your dbms_metadata.get_ddl output, why not select the output in a CLOB and write the CLOB to filesystem.
e.g.
DECLARE
data CLOB;
objType varchar2(30) := 'TABLE';
objSchema varchar2(30) := 'SCOTT';
objName varchar2(30) := 'EMP';
fname varchar2(256) := objType || '_' || objSchema || '_' || objName || '.sql';
BEGIN
SELECT dbms_metadata.get_ddl(objType,objName,objSchema) into data from dual;
DBMS_XSLPROCESSOR.CLOB2FILE(data,'DATA_PUMP_DIR',fname);
END;
/
This should get you correct DDL, w/o the output getting messed up. The only thing is that the script will be created on the DB server and not on the client from where you invoke sqlplus.
The script gets saved in the directory pointed to by the 'DATA_PUPM_DIR' entry on the DB Server. i.e.
select directory_path from all_directories where directory_name like 'DATA_PUMP_DIR';
What's more you can add some sort of iteration over all the tables/indexes etc of a schema, and get a complete schema's DDL in no time. I do it all the time.