it-swarm.it

Scrive Oracle DDL in modo automatizzato

Oracle SQL Developer è in grado di esportare DDL tramite Tools -> Database Export... Funziona molto bene, ma richiede un intervento manuale.

Conosco DBMS_METADATA.get_ddl(), ma ho scoperto che l'esportazione non è perfetta. Ho riscontrato problemi in cui il DDL DBMS_METADATA Esportato non era utilizzabile senza prima risolvere problemi come interruzioni nel mezzo di una parola chiave, e peggio. Tuttavia, se qualcuno conosce un modo per esportare DDL attraverso DMBS_METADATA Che può essere eseguito senza correzioni manuali, anche questa sarebbe un'ottima soluzione.

Fondamentalmente, sto cercando un modo automatico/programmabile per esportare DDL identico a ciò che viene esportato attraverso il modo manuale.

Come lo posso fare?

14
MatthewToday

Bene, se sqlplus sta rovinando il tuo output dbms_metadata.get_ddl, perché non selezionare l'output in un CLOB e scrivere il CLOB nel filesystem.

per esempio.

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

Questo dovrebbe darti DDL corretto, senza che l'output venga incasinato. L'unica cosa è che lo script verrà creato sul server DB e non sul client da cui si richiama sqlplus.

Lo script viene salvato nella directory indicata dalla voce 'DATA_PUPM_DIR' sul server DB. cioè.

select directory_path from all_directories where directory_name like 'DATA_PUMP_DIR';

Inoltre, puoi aggiungere una sorta di iterazione su tutte le tabelle/indici ecc. Di uno schema e ottenere il DDL di uno schema completo in pochissimo tempo. Lo faccio tutto il tempo.

5
user5294

Il motivo per cui stai riscontrando problemi con dbms_metadata.get_ddl è che genera CLOBs che possono avere dimensioni fino a 4 GB. Per impostazione predefinita, SQL * Plus e Oracle SQL Developer troncano il testo lungo in modo da non eliminare il client con grandi quantità di testo.

È molto semplice ignorare questo comportamento in SQL * Plus con alcuni comandi SET e ottenere DDL pulito.

Lo script di cui hai bisogno è:

-- 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;
6
Nick Chammas

Le seguenti trasformazioni possono essere d'aiuto. Non ho usato il metodo DBMS_XSLPROCESSOR.CLOB2FILE, ma li ho usati per migrare un database Oracle da Solaris a Linux. Non ho potuto usare il data pump a causa della versione di Oracle che stavano usando e del fatto che usavano tipi di dati XML per tipi di dati di colonna.

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