Автоматично виписуйте Oracle DDL


14

Oracle SQL Developer здатний експортувати DDL через Tools -> Database Export...Це працює дуже добре, але вимагає вручного втручання.

Я знаю DBMS_METADATA.get_ddl(), але виявив, що експорт не є ідеальним. Я зіткнувся з проблемами, де експортований DBMS_METADATADDL був непридатним для використання, не попередньо виправляючи такі проблеми, як перерви в середині ключового слова, і ще гірше. Однак, якщо хтось знає спосіб експорту DDL через нього DMBS_METADATA, він може працювати без ручних виправлень, це також буде чудовим рішенням.

В основному я шукаю автоматичний / сценарій для експорту DDL, ідентичний тому, що експортується вручну.

Як я можу це зробити?


1
Ви запускаєте DBMS_METADATA через SQLplus? У вас встановлена ​​ширина лінії> 80?
Девід Манн

Я використовую SQLPlus. Чи є краща утиліта? Ви маєте на увазі слово "встановити розмір ліній 200"? Це не має ніякого значення
MatthewToday

2
Здається, і інші мали проблеми. Помилка в більш ранніх версіях Oracle і труднощі з можливістю прекрасної відтворення DBMS_METADATA в наступних версіях asktom.oracle.com/pls/asktom/… Моє рішення не для вас таке чудове. Зазвичай я запускаю DBMS_METADATA у графічному інструменті (наприклад, Toad), а потім вирізаю та вставляю в текстовий документ. Однозначно не автоматизовано, але, здається, краще обробляти закінчення рядків CLOB.
Девід Манн

Гмм, схоже, я, можливо, зараз дотримуюся ручного способу ... Дякую за допомогу та посилання :)
MatthewToday

1
@David - Вам потрібно встановити ширину вихідного стовпчика, використовуючи COL, як показано в цьому прикладі , і він буде працювати.
Нік Шамма

Відповіді:


5

Що ж, якщо sqlplus накручує ваш dbms_metadata.get_ddl вихід, чому б не вибрати вихід у CLOB і записати CLOB у файлову систему.

напр

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

Це має надати вам правильний DDL, без виходу з ладу. Єдине, що сценарій буде створений на сервері БД, а не на клієнті, звідки ви викликаєте sqlplus.

Сценарій зберігається в каталозі, на який вказує запис "DATA_PUPM_DIR" на сервері БД. тобто

select directory_path from all_directories where directory_name like 'DATA_PUMP_DIR';

Більше того, ви можете додати якусь ітерацію для всіх таблиць / індексів тощо схеми, і отримати DDL повної схеми в найкоротші терміни. Я роблю це постійно.


2
Зауважте, це записує файл у файлову систему сервера. Хто бажає отримати DDL на клієнтській машині, цього досягти не вдасться.
Ендрю Спенсер

6

Причина, з якою у вас виникають проблеми, dbms_metadata.get_ddlполягає в тому, що вона виводить CLOBрозмір s, розміром до 4 Гб. За замовчуванням SQL * Plus і Oracle SQL Developer урізають довгий текст, щоб вони не перебирали клієнта з великими за допомогою тексту.

Дуже легко змінити таку поведінку в SQL * Plus за допомогою декількох SETкоманд та отримати чистий DDL.

Необхідний сценарій:

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

Наступні перетворення можуть допомогти. Я не використовував метод DBMS_XSLPROCESSOR.CLOB2FILE, але я їх використовував для переміщення бази даних Oracle з Solaris в Linux. Я не міг використовувати насос даних через версію Oracle, яку вони використовують, і те, що вони використовували типи даних XML для типів даних стовпців.

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 );
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.