자동화 된 방식으로 Oracle DDL 스크립팅


14

Oracle SQL Developer는 다음을 통해 DDL을 내보낼 수 있습니다. Tools -> Database Export...이 기능은 매우 효과적이지만 수동 개입이 필요합니다.

나는 알고 DBMS_METADATA.get_ddl()있지만 수출이 완벽하지 않다는 것을 알았습니다. DBMS_METADATA키워드 중간에 중단과 같은 문제를 먼저 수정하지 않고 내 보낸 DDL을 사용할 수없는 문제가 발생했습니다. 그러나 누구나 DMBS_METADATA수동으로 수정하지 않고 DDL을 내보내는 방법을 알고 있다면 훌륭한 해결책이 될 것입니다.

기본적으로 수동 방법으로 내보내는 것과 동일한 DDL을 내보내는 자동 / 스크립트 가능한 방법을 찾고 있습니다.

어떻게해야합니까?


1
SQLplus를 통해 DBMS_METADATA를 실행하고 있습니까? 선 너비를 80보다 크게 설정 했습니까?
David Mann

SQLPlus를 사용하고 있습니다. 더 나은 유틸리티가 있습니까? 'set linesize 200'을 의미합니까? 그것은 아무런 차이가 없습니다
MatthewToday

2
다른 사람들도 문제가있는 것 같습니다. 이전 버전의 Oracle의 버그로 인해 DBMS_METADATA가 이후 버전에서 잘 재생되지 않습니다. asktom.oracle.com/pls/asktom/… 내 솔루션은 그리 좋지 않습니다. 나는 보통 Toad와 같은 그래픽 도구에서 DBMS_METADATA를 실행 한 다음 텍스트 문서로 잘라 붙여 넣습니다. 확실히 자동화 할 수는 없지만 CLOB로 더 나은 줄 끝을 처리하는 것 같습니다.
David Mann

흠 내가 같은 외모는 이제 다음의 매뉴얼 방법을 고집 할 수 ... 감사합니다 :)하지만 도움말 및 링크
MatthewToday

1
@ 데이비드 - 당신하여 폭 출력 열을 설정할 필요 COL로 도시되어, 본 실시 예 , 그리고 작동 할 것이다.
Nick Chammas 2012 년

답변:


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를 호출하는 클라이언트가 아닌 DB 서버에서 작성된다는 것입니다.

스크립트는 DB 서버의 'DATA_PUPM_DIR'항목이 가리키는 디렉토리에 저장됩니다. 즉

select directory_path from all_directories where directory_name like 'DATA_PUMP_DIR';

또한 스키마의 모든 테이블 / 인덱스에 대해 일종의 반복을 추가하고 완전한 스키마의 DDL을 즉시 얻을 수 있습니다. 나는 항상 그것을한다.


2
이것은 파일을 서버의 파일 시스템에 씁니다. 클라이언트 시스템에서 DDL을 얻으려는 사람은 그렇게 할 수 없습니다.
Andrew Spencer

6

문제가있는 이유는 최대 4GB의 크기를 dbms_metadata.get_ddl출력 CLOB하기 때문입니다. 기본적으로 SQL * Plus 및 Oracle SQL Developer는 긴 텍스트를 자르기 때문에 긴 텍스트를 자르지 않으므로 긴 텍스트를 자릅니다.

몇 가지 SET명령 으로 SQL * Plus에서이 동작을 무시 하고 깔끔한 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 );
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.