Erstellen Sie ein automatisiertes Skript für Oracle DDL

14

Oracle SQL Developer kann DDL über exportieren. Tools -> Database Export...Dies funktioniert sehr gut, erfordert jedoch manuelle Eingriffe.

Ich weiß von DBMS_METADATA.get_ddl(), habe aber festgestellt, dass der Export nicht perfekt ist. Ich bin auf Probleme DBMS_METADATAgestoßen, bei denen die exportierte DDL nicht verwendet werden konnte, ohne zuvor Probleme wie Pausen in der Mitte eines Schlüsselworts und noch schlimmer zu beheben. Wenn jedoch jemand eine Möglichkeit zum Exportieren von DDL kennt DMBS_METADATA, die ohne manuelle Korrekturen ausgeführt werden kann, ist dies auch eine großartige Lösung.

Grundsätzlich suche ich nach einer automatischen / skriptfähigen Methode zum Exportieren von DDL, die mit der manuellen Methode identisch ist.

Wie kann ich das machen?

MatthewToday
quelle
1
Führen Sie DBMS_METADATA über SQLplus aus? Haben Sie eine Linienbreite von> 80 eingestellt?
David Mann
Ich benutze SQLPlus. Gibt es ein besseres Dienstprogramm? Meinen Sie mit "Liniengröße 200 einstellen"? Das macht keinen Unterschied
MatthewToday
2
Andere hatten anscheinend auch Probleme. Fehler in früheren Versionen von Oracle und Schwierigkeiten beim Ausführen von DBMS_METADATA in späteren Versionen. asktom.oracle.com/pls/asktom/… Meine Lösung ist nicht so gut für Sie. Normalerweise führe ich DBMS_METADATA in einem grafischen Tool (wie Toad) aus und schneide es dann aus und füge es in ein Textdokument ein. Auf jeden Fall nicht automatisierbar, aber es scheint die Zeilenenden mit CLOBs schöner zu behandeln.
David Mann
Hmmm sieht so aus, als würde ich mich vorerst an die manuelle Vorgehensweise halten ... Vielen Dank für die Hilfe und den Link :)
MatthewToday,
1
@David - Sie müssen die Breite der Ausgabespalte COLwie in diesem Beispiel gezeigt mit festlegen , damit dies funktioniert.
Nick Chammas

Antworten:

5

Nun, wenn sqlplus Ihre dbms_metadata.get_ddl-Ausgabe verschraubt, warum nicht die Ausgabe in einem CLOB auswählen und das CLOB in das Dateisystem schreiben?

z.B

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

Dadurch sollten Sie die korrekte DDL erhalten, ohne dass die Ausgabe durcheinander kommt. Das Skript wird nur auf dem DB-Server und nicht auf dem Client erstellt, von dem aus Sie sqlplus aufrufen.

Das Skript wird in dem Verzeichnis gespeichert, auf das der Eintrag 'DATA_PUPM_DIR' auf dem DB-Server verweist. dh

select directory_path from all_directories where directory_name like 'DATA_PUMP_DIR';

Außerdem können Sie eine Art Iteration über alle Tabellen / Indizes usw. eines Schemas hinzufügen und in kürzester Zeit die DDL eines vollständigen Schemas abrufen. Das mache ich die ganze Zeit.


quelle
2
Beachten Sie, dass dadurch die Datei in das Dateisystem des Servers geschrieben wird. Wer die DDL auf dem Client-Rechner erhalten möchte, wird dies nicht erreichen.
Andrew Spencer
6

Der Grund, mit dem Sie Probleme haben, dbms_metadata.get_ddlbesteht darin, dass es CLOBs ausgibt, die bis zu 4 GB groß sein können. Standardmäßig kürzen SQL * Plus und Oracle SQL Developer langen Text, damit der Client nicht mit großen Textmengen in den Papierkorb verschoben wird.

Es ist sehr einfach, dieses Verhalten in SQL * Plus mit ein paar SETBefehlen zu überschreiben und eine saubere DDL zu erhalten.

Das Skript, das Sie benötigen, ist:

-- 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
quelle
0

Die folgenden Transformationen können hilfreich sein. Ich habe die DBMS_XSLPROCESSOR.CLOB2FILE-Methode nicht verwendet, aber ich habe sie verwendet, um eine Oracle-Datenbank von Solaris nach Linux zu migrieren. Ich konnte Data Pump aufgrund der verwendeten Oracle-Version und der Tatsache, dass XML-Datentypen für Spaltendatentypen verwendet wurden, nicht verwenden.

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
quelle