Script Oracle DDL de manera automatizada


14

Oracle SQL Developer puede exportar DDL a través de Tools -> Database Export...Esto funciona muy bien, pero requiere intervención manual.

Lo sé DBMS_METADATA.get_ddl(), pero he descubierto que la exportación no es perfecta. Me encontré con problemas en los que el DBMS_METADATADDL exportado no era utilizable sin solucionar primero problemas como saltos en el medio de una palabra clave, y peor. Sin embargo, si alguien conoce una forma de exportar DDL a través de DMBS_METADATAeso que puede ejecutarse sin arreglos manuales, esa sería una gran solución también.

Básicamente, estoy buscando una forma automática / programable para exportar DDL idéntico a lo que se exporta a través de la forma manual.

¿Cómo puedo hacer eso?


1
¿Está ejecutando DBMS_METADATA a través de SQLplus? ¿Tiene el ancho de línea establecido> 80?
— David Mann el

Estoy usando SQLPlus. ¿Hay una mejor utilidad? ¿Quieres decir con 'set linesize 200'? Eso no hace ninguna diferencia
— MatthewToday

2
Parece que otros también tuvieron problemas. Error en versiones anteriores de Oracle, y dificultad para hacer que DBMS_METADATA funcione bien en versiones posteriores. asktom.oracle.com/pls/asktom/… Mi solución no es tan buena para ti. Normalmente ejecuto DBMS_METADATA en una herramienta gráfica (como Toad) y luego corto y pego en un documento de texto. Definitivamente no es automatizable, pero parece manejar mejor las terminaciones de línea con CLOB.
— David Mann

Hmmm parece que podrían estar pegadas con la forma manual por ahora entonces ... Gracias por la ayuda y el enlace aunque :)
— MatthewToday

1
@David: debe establecer el ancho de la columna de salida utilizando COL, como se muestra en este ejemplo , y funcionará.
— Nick Chammas

Respuestas:


5

Bueno, si sqlplus está arruinando su salida dbms_metadata.get_ddl, ¿por qué no seleccionar la salida en un CLOB y escribir el CLOB en el sistema de archivos?

p.ej

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;
/

Esto debería obtener el DDL correcto, sin que la salida se estropee. Lo único es que el script se creará en el servidor de base de datos y no en el cliente desde el que invoca sqlplus.

El script se guarda en el directorio señalado por la entrada 'DATA_PUPM_DIR' en el Servidor DB. es decir

select directory_path from all_directories where directory_name like 'DATA_PUMP_DIR';

Además, puede agregar algún tipo de iteración sobre todas las tablas / índices, etc. de un esquema, y ​​obtener un DDL de un esquema completo en poco tiempo. Lo hago todo el tiempo.


2
Tenga en cuenta que esto escribe el archivo en el sistema de archivos del servidor. Cualquiera que busque obtener el DDL en la máquina del cliente, esto no lo logrará.
— Andrew Spencer

6

La razón por la que tiene problemas dbms_metadata.get_ddles porque produce CLOBs que pueden tener hasta 4 GB de tamaño. De manera predeterminada, SQL * Plus y Oracle SQL Developer truncan el texto largo para que no arrojen basura al cliente con grandes cantidades de texto.

Es muy fácil anular este comportamiento en SQL * Plus con algunos SETcomandos y obtener DDL limpio.

El script que necesitas es:

-- 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;

0

Las siguientes transformaciones pueden ayudar. No he usado el método DBMS_XSLPROCESSOR.CLOB2FILE, pero sí los utilicé para migrar una base de datos Oracle de Solaris a Linux. No pude usar la bomba de datos debido a la versión de Oracle que estaban usando y al hecho de que usaban tipos de datos XML para los tipos de datos de columna.

DBMS_METADATA.SET_TRANSFORM_PARAM( DBMS_METADATA.SESSION_TRANSFORM, 'PRETTY',             TRUE );
DBMS_METADATA.SET_TRANSFORM_PARAM( DBMS_METADATA.SESSION_TRANSFORM, 'SQLTERMINATOR',      TRUE );
DBMS_METADATA.SET_TRANSFORM_PARAM( DBMS_METADATA.SESSION_TRANSFORM, 'REF_CONSTRAINTS',    FALSE);
DBMS_METADATA.SET_TRANSFORM_PARAM( DBMS_METADATA.SESSION_TRANSFORM, 'OID',                FALSE);
DBMS_METADATA.SET_TRANSFORM_PARAM( DBMS_METADATA.SESSION_TRANSFORM, 'SEGMENT_ATTRIBUTES', FALSE);
DBMS_METADATA.SET_TRANSFORM_PARAM( DBMS_METADATA.SESSION_TRANSFORM, 'TABLESPACE',         TRUE );
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.