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.