카테고리 보관물: Sql

sql

자동화 된 방식으로 Oracle DDL 스크립팅 DBMS_METADATA.get_ddl()있지만 수출이 완벽하지 않다는

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

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

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

어떻게해야합니까?



답변

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을 즉시 얻을 수 있습니다. 나는 항상 그것을한다.


답변

문제가있는 이유는 최대 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;


답변

다음과 같은 변환이 도움이 될 수 있습니다. 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 );


답변