Script out Oracle DDL dengan cara otomatis

14

Oracle SQL Developer dapat mengekspor DDL melalui Tools -> Database Export...Ini bekerja dengan sangat baik, tetapi membutuhkan intervensi manual.

Saya tahu DBMS_METADATA.get_ddl(), tetapi ternyata ekspornya tidak sempurna. Saya mengalami masalah di mana DBMS_METADATADDL yang diekspor tidak dapat digunakan tanpa terlebih dahulu memperbaiki masalah seperti jeda di tengah kata kunci, dan lebih buruk. Namun, jika ada yang tahu cara mengekspor DDL melalui DMBS_METADATAitu dapat berjalan tanpa perbaikan manual, itu akan menjadi solusi yang bagus juga.

Pada dasarnya, saya mencari cara otomatis / skrip untuk mengekspor DDL identik dengan apa yang diekspor melalui cara manual.

Bagaimana saya bisa melakukan itu?

MatthewHari ini
sumber
1
Apakah Anda menjalankan DBMS_METADATA melalui SQLplus? Apakah Anda memiliki lebar garis yang ditetapkan> 80?
David Mann
Saya menggunakan SQLPlus. Apakah ada utilitas yang lebih baik? Apakah yang Anda maksud dengan 'set linesize 200'? Itu tidak ada bedanya
MatthewToday
2
Sepertinya orang lain juga punya masalah. Bug di versi Oracle yang lebih lama, dan kesulitan membuat DBMS_METADATA bermain dengan baik di versi yang lebih baru. asktom.oracle.com/pls/asktom/… Solusi saya tidak begitu bagus untuk Anda. Saya biasanya menjalankan DBMS_METADATA dalam alat grafis (seperti Toad) dan kemudian memotong dan menempel ke dokumen teks. Jelas tidak automatable, tetapi tampaknya menangani akhiran baris dengan CLOBs lebih bagus.
David Mann
Hmmm sepertinya saya mungkin bertahan dengan cara manual untuk saat ini ... Terima kasih atas bantuan dan tautannya :)
MatthewToday
1
@ David - Anda perlu mengatur lebar kolom output menggunakan COL, seperti yang ditunjukkan dalam contoh ini , dan itu akan berhasil.
Nick Chammas

Jawaban:

5

Nah, jika sqlplus mengacaukan output dbms_metadata.get_ddl Anda, mengapa tidak memilih output dalam CLOB dan menulis CLOB ke filesystem.

misalnya

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

Ini akan membuat Anda benar DDL, tanpa output menjadi kacau. Satu-satunya hal adalah bahwa skrip akan dibuat pada server DB dan bukan pada klien dari mana Anda memanggil sqlplus.

Script akan disimpan dalam direktori yang ditunjuk oleh entri 'DATA_PUPM_DIR' pada DB Server. yaitu

select directory_path from all_directories where directory_name like 'DATA_PUMP_DIR';

Terlebih lagi, Anda dapat menambahkan semacam iterasi pada semua tabel / indeks dll dari suatu skema, dan mendapatkan DDL skema lengkap dalam waktu singkat. Saya selalu melakukannya.


sumber
2
Catatan, ini menulis file ke sistem file server. Siapa pun yang ingin mendapatkan DDL pada mesin klien, ini tidak akan mencapainya.
Andrew Spencer
6

Alasan Anda mengalami masalah dbms_metadata.get_ddladalah karena outputnya CLOByang dapat mencapai 4GB. Secara default, SQL * Plus dan Oracle SQL Developer memotong teks panjang sehingga mereka tidak membuang klien dengan sekumpulan besar teks.

Sangat mudah untuk menimpa perilaku ini di SQL * Plus dengan beberapa SETperintah dan mendapatkan DDL bersih.

Skrip yang Anda butuhkan adalah:

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

Transformasi berikut dapat membantu. Saya belum menggunakan metode DBMS_XSLPROCESSOR.CLOB2FILE, tapi saya menggunakannya untuk memigrasi database Oracle dari Solaris ke Linux. Saya tidak bisa menggunakan pompa data karena versi Oracle yang mereka gunakan dan fakta bahwa mereka menggunakan tipe data XML untuk tipe data kolom.

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
sumber