web-dev-qa-db-ja.com

自動化された方法でOracle DDLをスクリプト化

Oracle SQL Developerは_Tools -> Database Export..._を介してDDLをエクスポートできます。これは非常にうまく機能しますが、手動による介入が必要です。

私はDBMS_METADATA.get_ddl()を知っていますが、エクスポートが完全ではないことがわかりました。エクスポートされた_DBMS_METADATA_ DDLが、キーワードの途中での中断などの問題を修正せずに使用できなかったり、さらに悪い問題が発生したりしました。ただし、誰かが_DMBS_METADATA_を介してDDLをエクスポートする方法を知っていて、手動で修正しなくても実行できる場合、それも素晴らしい解決策になります。

基本的に、DDL identicalを手動の方法でエクスポートされるものにエクスポートする自動/スクリプト可能な方法を探しています。

どうやってやるの?

14
MatthewToday

さて、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を取得できます。私はいつもそれをしています。

5
user5294

dbms_metadata.get_ddlで問題が発生するのは、最大4GBのCLOBsが出力されるためです。デフォルトでは、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;
6
Nick Chammas

次の変換が役立つ場合があります。 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 );
0
Gandolf989