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


14

Oracle SQL DeveloperはTools -> Database Export...これを介してDDLをエクスポートできますが、これは非常に効果的ですが、手動による介入が必要です。

私は知っDBMS_METADATA.get_ddl()ていますが、エクスポートが完璧ではないことを発見しました。エクスポートされたDBMS_METADATADDLが、キーワードの途中での区切りなどの問題を修正することなく使用できないという問題に遭遇しました。ただし、DMBS_METADATA手動で修正することなく実行できるDDLのエクスポート方法を知っている人がいれば、それも素晴らしい解決策になります。

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

どうやってやるの?


1
SQLplus経由でDBMS_METADATAを実行していますか?80を超える線幅を設定していますか?
デビッドマン

SQLPlusを使用しています。より良いユーティリティはありますか?「set linesize 200」とはどういう意味ですか?それは違いはありません
MatthewToday

2
他にも問題があったようです。Oracleの以前のバージョンのバグ、およびそれ以降のバージョンでDBMS_METADATAをうまく再生するのが難しい。asktom.oracle.com/pls/asktom / ...私の解決策はあなたにとってそれほど素晴らしいものではありません。通常、グラフィカルツール(Toadなど)でDBMS_METADATAを実行してから、テキストドキュメントにカットアンドペーストします。間違いなく自動化できませんが、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を呼び出したクライアントではなく、DBサーバーでスクリプトが作成されることです。

スクリプトは、DBサーバーの「DATA_PUPM_DIR」エントリが指すディレクトリに保存されます。すなわち

select directory_path from all_directories where directory_name like 'DATA_PUMP_DIR';

さらに、スキーマのすべてのテーブル/インデックスなどに対して何らかの反復を追加し、すぐに完全なスキーマのDDLを取得できます。私はいつもそれをします。


2
これにより、ファイルがサーバーのファイルシステムに書き込まれます。クライアントマシンでDDLを取得しようとしている人は、これを達成できません。
アンドリュースペンサー14年

6

問題があるのdbms_metadata.get_ddlは、CLOB最大4GBのサイズを出力できるためです。デフォルトでは、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.