Сценарий Oracle DDL в автоматическом режиме

14

Oracle SQL Developer может экспортировать DDL через Tools -> Database Export...Это работает очень хорошо, но требует ручного вмешательства.

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

По сути, я ищу автоматический / скриптовый способ экспорта DDL, идентичный тому, который экспортируется ручным способом.

Как я могу это сделать?

MatthewToday
источник
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размером до 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 );
Gandolf989
источник