Faça o script do DDL do Oracle de maneira automatizada

14

O Oracle SQL Developer é capaz de exportar DDL através. Tools -> Database Export...Isso funciona muito bem, mas requer intervenção manual.

Eu sei DBMS_METADATA.get_ddl(), mas descobri que a exportação não é perfeita. Encontrei problemas em que o DBMS_METADATADDL exportado não era utilizável sem antes corrigir problemas como quebras no meio de uma palavra-chave e coisa pior. No entanto, se alguém souber uma maneira de exportar DDL através DMBS_METADATAque possa ser executada sem correções manuais, isso também seria uma ótima solução.

Basicamente, estou procurando uma maneira automática / programável de exportar DDL idêntico ao que é exportado pela maneira manual.

Como eu posso fazer isso?

MatthewToday
fonte
1
Você está executando o DBMS_METADATA via SQLplus? Você tem a largura da linha definida> 80?
David Mann
Estou usando o SQLPlus. Existe um utilitário melhor? Você quer dizer com 'definir tamanho da linha 200'? Isso não faz diferença
MatthewToday
2
Parece que outros tiveram problemas também. Erro nas versões anteriores do Oracle e dificuldade em fazer com que o DBMS_METADATA funcione bem nas versões posteriores. asktom.oracle.com/pls/asktom/… Minha solução não é tão boa para você. Normalmente, executo o DBMS_METADATA em uma ferramenta gráfica (como o Toad) e depois recordo e colo em um documento de texto. Definitivamente não é automatizável, mas parece lidar com as terminações de linha com os CLOBs mais agradáveis.
David Mann
Hmmm parece que eu poderia estar furando com a maneira manual para agora então ... Obrigado pela ajuda e ligação embora :)
MatthewToday
1
@ David - Você precisa definir a largura da coluna de saída usando COL, como é mostrado neste exemplo , e funcionará.
21412 Nick Chammas

Respostas:

5

Bem, se o sqlplus está danificando sua saída dbms_metadata.get_ddl, por que não selecionar a saída em um CLOB e gravar o CLOB no sistema de arquivos.

por exemplo

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

Isso deve fazer com que você DDL correto, sem que a saída seja prejudicada. A única coisa é que o script será criado no servidor do banco de dados e não no cliente de onde você chama o sqlplus.

O script é salvo no diretório apontado pela entrada 'DATA_PUPM_DIR' no DB Server. ie

select directory_path from all_directories where directory_name like 'DATA_PUMP_DIR';

Além do mais, você pode adicionar algum tipo de iteração em todas as tabelas / índices etc. de um esquema e obter o DDL completo de um esquema rapidamente. Eu faço isso o tempo todo.


fonte
2
Observe que isso grava o arquivo no sistema de arquivos do servidor. Qualquer pessoa que queira obter o DDL na máquina cliente, isso não será possível.
Andrew Spencer
6

O motivo pelo qual você está tendo problemas dbms_metadata.get_ddlé que ele gera CLOBs com tamanho de até 4 GB. Por padrão, o SQL * Plus e o Oracle SQL Developer truncam o texto longo para que eles não joguem o lixo no lixo com grandes quantidades de texto.

É muito fácil substituir esse comportamento no SQL * Plus com alguns SETcomandos e obter uma DDL limpa.

O script que você precisa é:

-- 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;
Nick Chammas
fonte
0

As seguintes transformações podem ajudar. Não usei o método DBMS_XSLPROCESSOR.CLOB2FILE, mas usei-os para migrar um banco de dados Oracle do Solaris para o Linux. Não pude usar a bomba de dados devido à versão do Oracle que eles estavam usando e ao fato de usarem tipos de dados XML para tipos de dados de coluna.

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 );
Gandolf989
fonte