1

リモートOracleインスタンスに接続し、ストアドプロシージャをそれぞれ独自のファイルにコピーするantタスクを作成できるようにしたいと考えています。私は実行するant sqlタスクを持つことができることを知っています

SELECT object_type, 
       object_name, 
       dbms_metadata.get_ddl(object_type, object_name) object_ddl 
FROM user_objects
WHERE OBJECT_TYPE in ('INDEX', 'TRIGGER', 'TABLE', 'VIEW', 'PACKAGE', 'FUNCTION', 'PROCEDURE', 'SYNONYM', 'TYPE')  
ORDER BY OBJECT_TYPE, OBJECT_NAME

しかし、これは結果セットをすべて1つのファイルにまとめますが、各手順ごとにファイルが必要です(これは、後でSVNの内容と比較するためです)。

何か案は?

ありがとう!アレックス

4

3 に答える 3

1

アレクサンダー、あなたの助けに本当に感謝します。これがあなたの提案に基づいて私が使用したコードです。唯一の免責事項は、clobをvarchar2に変換するためにdbms_lob.substrを実行する必要があったため、取得できる最大値は各プロシージャddlから4000文字であり、この変換中にフォーマットが強制終了され、すべて1行になってしまうことです。これらの2つの問題を修正する方法について何かアイデアがあれば、私に知らせてください。

<target name="retrieve_procedures_names" depends="environment">

    <sql driver="${mp.db.driver.class}" url="${mp.db.connection.url}" userid="${mp.db.user.name}"
         password="${mp.db.password}" print="yes"
         output="${db.tmp.dir}/procedure_names.txt" onerror="stop" autocommit="true" encoding="UTF-8"
         showheaders="false" showtrailers="false">
        <classpath location="${db.driver.jar}"/>
        SELECT OBJECT_NAME FROM user_objects WHERE OBJECT_TYPE = 'PROCEDURE'
    </sql>

</target>
<target name="retrieve_procedures" depends="retrieve_procedures_names">
    <loadfile property="procnames" srcfile="${db.tmp.dir}/procedure_names.txt"/>
    <for list="${procnames}" delimiter="${line.separator}" param="sproc-name">
        <sequential>
            <sql driver="${mp.db.driver.class}" url="${mp.db.connection.url}" userid="${mp.db.user.name}"
                 password="${mp.db.password}" print="yes"
                 output="${db.tmp.dir}/@{sproc-name}.txt" onerror="stop" autocommit="true" encoding="UTF-8"
                 keepformat="true" showheaders="false" showtrailers="false">
                <classpath location="${db.driver.jar}"/>
                SELECT dbms_lob.substr(dbms_metadata.get_ddl(object_type, object_name), 4000, 1) FROM user_objects
                WHERE OBJECT_TYPE = 'PROCEDURE' and upper(object_name) = '@{sproc-name}'
            </sql>
        </sequential>
    </for>

</target>
于 2009-10-13T18:16:52.180 に答える
1

SQL ステートメントを作成し、データベース サーバーからマシンに結果を取得する方法について、最も難しい部分をすでに理解しているようです。

今、これを行います。

  1. すべてのストアド プロシージャ名を取得する SQL ステートメントを作成します。
  2. 実行する<loadfile property="procnames" file="result-of-sql-run.txt"/>
  3. タスクにantcontrib を使用して、ストアド プロシージャ名を反復処理する

反復する方法は次のとおりです。

   <for list="${procnames}" delimeter="..." param="sproc-name">
      <sequential>
        <!-- Construct a new SQL statement to get specific
             stored procedure named @{sproc-name} -->
     </sequential>
   </for>

SQL コードを実行し、ant からデータベースに接続する方法を知りたいのですが、ソリューションを公開できますか?

于 2009-10-13T01:43:28.067 に答える
0

私は似たようなことをしました。DDL エクストラクタ/ファイル クリエータを別の言語 (私は Perl を使用) で記述し、Ant execタスクで起動することをお勧めします。言語を使用すると、「SELECT DBMS_METADATA.GET_DDL...」メソッドよりもいくつかの利点があります。

(注: これから作成する外部プログラムは、まだ DBMS_METADATA.GET_DDL のラッパーです)

  • DBMS_METADATA.SET_TRANSFORM_PARAM オプションをプログラムで設定して、ソース管理標準により適合させることができます。

  • 必要に応じて、スキーマ修飾子を取り除くことができます。

  • オブジェクトが元々ソース管理から Ant を介してデプロイされていない場合は、他のクライアント プログラムが導入する可能性のあるいくつかの単純な空白変換を行うことで、ミスマッチ ノイズを減らすことができます。

  • その標準があれば、生成するファイルの拡張子をより適切に制御できます (たとえば、トリガーの場合は ".trg")。

于 2009-10-13T12:32:01.713 に答える