Scrive Oracle DDL in modo automatizzato


14

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

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

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

Come posso fare ciò?


1
Stai eseguendo DBMS_METADATA tramite SQLplus? La larghezza della linea è impostata su> 80?
David Mann,

Sto usando SQLPlus. C'è un'utilità migliore? Vuoi dire con 'set sizeize 200'? Non fa differenza
Matthew, oggi

2
Sembra che anche altri abbiano avuto problemi. Bug nelle versioni precedenti di Oracle e difficoltà a far funzionare bene DBMS_METADATA nelle versioni successive. asktom.oracle.com/pls/asktom/… La mia soluzione non è eccezionale per te. Di solito eseguo DBMS_METADATA in uno strumento grafico (come Toad) e quindi taglio e incolla in un documento di testo. Sicuramente non automatizzabile, ma sembra gestire le terminazioni di linea con CLOB più belli.
David Mann,

Hmmm sembra che per il momento potrei essere fedele al modo manuale ... Grazie per l'aiuto e il collegamento però :)
MatthewToday

1
@David - Devi impostare la larghezza della colonna di output usando COL, come mostrato in questo esempio , e funzionerà.
Nick Chammas,

Risposte:


5

Bene, se sqlplus sta rovinando l'output di 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. vale a dire

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.


2
Nota, questo scrive il file nel filesystem del server. Chiunque cerchi di ottenere il DDL sul computer client, questo non lo farà.
Andrew Spencer,

6

Il motivo per cui si riscontrano problemi 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 pochi SETcomandi 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;

0

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 i tipi di dati XML per i tipi di dati delle colonne.

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 );
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.