Oracle DDL'yi otomatik bir şekilde yazın


14

Oracle SQL Developer, DDL'yi dışa aktarabilir Tools -> Database Export...Bu çok iyi çalışır, ancak manuel müdahale gerektirir.

Biliyorum DBMS_METADATA.get_ddl()ama ihracatın mükemmel olmadığını gördüm . Dışa aktarılan DBMS_METADATADDL'nin, bir anahtar kelimenin ortasındaki kesintiler gibi sorunları düzeltmeden ve daha kötüsü olmadan kullanılamadığı sorunlarla karşılaştım. Ancak, herhangi biri DMBS_METADATAmanuel düzeltmeler olmadan çalıştırarak DDL'yi dışa aktarmanın bir yolunu biliyorsa , bu da harika bir çözüm olacaktır.

Temel olarak, manuel yolla ihraç edilenle aynı DDL'yi dışa aktarmak için otomatik / yazılabilir bir yol arıyorum .

Bunu nasıl yapabilirim?


1
DBMS_METADATA'yı SQLplus üzerinden mi çalıştırıyorsunuz? Çizgi genişliğiniz> 80 olarak ayarlandı mı?
David Mann

SQLPlus kullanıyorum. Daha iyi bir yardımcı program var mı? Şunu mu demek istediniz: 'set linesize 200'? Bu hiç fark etmez
MatthewToday

2
Başkalarının da problemleri var gibi görünüyor. Oracle'ın önceki sürümlerinde hata ve DBMS_METADATA'nın sonraki sürümlerde güzel oynatılmasında zorluk. asktom.oracle.com/pls/asktom/… Çözümüm sizin için çok iyi değil. Genellikle DBMS_METADATA'yı grafiksel bir araçta (Kurbağa gibi) çalıştırırım ve sonra kesip bir metin belgesine yapıştırırım. Kesinlikle otomatikleştirilemez, ancak satır sonlarını daha güzel CLOBs ile işlemek gibi görünüyor.
David Mann

Hmmm şimdilik manuel yolla devam ediyor olabilirim ... Yine de yardım ve bağlantı için teşekkürler :)
MatthewToday 29:11

1
@David - Bu örnekteCOL gösterildiği gibi çıktı sütun genişliğini ayarlamanız gerekir ve çalışır.
Nick Chammas

Yanıtlar:


5

Eğer sqlplus dbms_metadata.get_ddl çıktısını vidalıyorsa, neden bir CLOB'de çıktıyı seçip CLOB'u dosya sistemine yazmıyorsunuz?

Örneğin

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

Bu, çıkışın dağılması olmadan doğru DDL'yi almanızı sağlayacaktır. Tek şey, komut dosyasının sqlplus'ı çağırdığınız istemcide değil, DB sunucusunda oluşturulacağıdır.

Komut dosyası, DB Sunucusundaki 'DATA_PUPM_DIR' girişi ile gösterilen dizine kaydedilir. yani

select directory_path from all_directories where directory_name like 'DATA_PUMP_DIR';

Dahası, bir şemanın tüm tabloları / dizinleri vb. Üzerine bir çeşit yineleme ekleyebilir ve hemen şemanın DDL'sini hemen alabilirsiniz. Onu her zaman yaparım.


2
Not, bu dosyayı sunucunun dosya sistemine yazar. İstemci makinede DDL almak isteyen herkes bunu başaramaz.
Andrew Spencer

6

Sorun yaşamanızın nedeni 4 GB'a kadar çıkabilen s dbms_metadata.get_ddlçıkışlarıdır CLOB. Varsayılan olarak, SQL * Plus ve Oracle SQL Developer uzun metni keser, böylece istemciyi büyük metin yığınlarıyla çöpe atmazlar.

SQL * Plus'ta bu davranışı birkaç SETkomutla geçersiz kılmak ve temiz DDL almak çok kolaydır .

İhtiyacınız olan komut dosyası:

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

Aşağıdaki dönüşümler yardımcı olabilir. DBMS_XSLPROCESSOR.CLOB2FILE yöntemini kullanmadım, ancak bunları Oracle veritabanını Solaris'ten Linux'a geçirmek için kullandım. Veri pompasını kullandıkları Oracle sürümü ve sütun veri türleri için XML veri türlerini kullandıkları için kullanamadım.

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 );
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.