SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

条件付きコンパイルを使ってOracleの運用コードを効率化する

パフォーマンスを低下させることなく可能な限りデバッグコードを挿入する方法

バージョン依存の条件付きコンパイル

 冒頭でも述べたように、Oracle RDBMSの最新の機能を活用するために、対象データベースのバージョンに応じて異なるコードをコンパイルしなければならない場合はよくあります。PL/SQL条件付きコンパイルでこれをもっと簡単に行えるようにするために、10gR2リリースには新しいPL/SQL提供パッケージのDBMS_DB_VERSIONが付属しています。このパッケージは、バージョン番号とリリース番号を保持する単純な定数の集まりです。DBMS_DB_VERSIONを使用するコードは次のようになります。

...
$IF DBMS_DB_VERSION.VERSION=10 $THEN
... [version 10 code] ...
$ELSE
... [code for earlier versions]...
$END
...

 コンパイル時に、2つの分岐の一方だけがパッケージにコンパイルされるので、メモリとオーバーヘッドの節約になります。

 DBMS_DB_VERSIONパッケージの定数の詳細については、PL/SQLの提供パッケージに関するドキュメントを参照してください。

10gR2以前のデータベースでの条件付きコンパイル

 PL/SQL条件付きコンパイルが10gR2の新しい機能であるなら、バージョン依存の条件付きコンパイルが何の役に立つのかと思う人もいるでしょう。実は、Oracleはこの新しい機能を以前のリリースにさかのぼって取り込むというきわめて異例の措置を講じています。PL/SQL条件付きコンパイルは、9iR2では9.2.0.6以降のパッチセットで、10gR1では10.1.0.4以降のパッチセットで利用できます。9.2.0.6では条件付きコンパイルがデフォルトで無効になっていますが、アンダースコア(隠し)パラメータを設定して有効にすることができます。10.1.0.4では、機能がデフォルトで有効になっていますが、同じアンダースコアパラメータを使って無効にすることができます(Oracleでは、Oracle技術サポートが直接指示したアンダースコアパラメータの値の変更のみをサポートしていることに注意してください)。10.2では、条件付きコンパイルを無効にすることはできず、アンダースコアパラメータは非推奨になっています。

DBMS_PREPROCESSORによる条件付きコンパイルの結果の確認

 コードに条件付きコンパイルのディレクティブが含まれている場合、DBA_SOURCE内のコードはメモリ内のコンパイル済みコードと一致しなくなります。DBA_SOURCE内のテキストには、ソースのコンパイラディレクティブとすべての分岐が含まれます。幸い、新しい提供パッケージのDBMS_PREPROCESSORを使うと、コンパイル後のコードを確認することができます。

 簡単な例として、先ほど軽量のデバッグフレームワークで使ったDebugPkgのコードに対してDBMS_PREPROCESSOR.PRINT_POST_PROCESSED_SOURCEを実行するとどうなるか見てみましょう(格納された定数DebugConstants.c_debugはFALSEに設定したままです)。

 最初に、ccflagのdebug_onをTRUEに設定し、デバッグコードを含めてDebugPkgをコンパイルします。

SQL> alter package debugpkg compile plsql_ccflags =
 'debug_on:true' reuse settings ;

Package altered.

 次に、DBMS_PREPROCESSOR.PRINT_POST_PROCESSED_SOURCEを実行し、コンパイル済みのコードがどのようになるかを確認します。

SQL> begin
  2> dbms_preprocessor.print_post_processed_source
  3>  ('PACKAGE BODY','BULKLOAD','DEBUGPKG');
  4>  end;
  5>  /

package body debugpkg is
  procedure debug (p_msg in varchar2, p_lineNum in number,
 p_plsUnit in varchar2) is
    v_error_string varchar2(32767);
  begin

    v_error_string := 'ERROR in ' || p_plsUnit || ', at line '
 || p_lineNum || ': ' || p_msg;

dbms_output.put_line(substr(v_error_string,1,255));

  end debug;
end debugpkg;

PL/SQL procedure successfully completed.

 ご覧のように、コンパイル済みのソースには選択ディレクティブの$IF...$ENDがなく、デバッグコードを指定したコード分岐だけが含まれています。ccflagのdebug_onをFALSEに設定してDebugPkgを再コンパイルすると、代わりにもう一方の分岐が表示されます。

SQL> alter package debugpkg compile plsql_ccflags =
 'debug_on:false' reuse settings ;

Package altered.

SQL> begin
  2> dbms_preprocessor.print_post_processed_source
  6>  ('PACKAGE BODY','BULKLOAD','DEBUGPKG');
  7>  end;
  8>  /
package body debugpkg is
  procedure debug (p_msg in varchar2, p_lineNum in number,
 p_plsUnit in varchar2) is
    v_error_string varchar2(32767);
  begin
    null;

  end debug;
end debugpkg;

PL/SQL procedure successfully completed.

 DBMS_PREPROCESSORを使用するときは、次の点に注意してください。

  • 渡されるストアドプロシージャが有効である必要はありません。
  • 匿名のPL/SQLブロック、またはソース行のPL/SQL表を渡すこともできます。
  • 関連する関数のGET_POST_PROCESSED_SOURCEは、処理後のソースコードをDBMS_OUTPUT.PUT_LINEで出力する代わりに、ソース行のPL/SQL表として返します。

 エラーディレクティブを含むコードに対してDBMS_PREPROCESSORを実行すると、結果の該当する場所にエラーが表示されます。

SQL> begin
  2> dbms_preprocessor.print_post_processed_source
  9>  ('PACKAGE BODY','BULKLOAD',
 10>   'TESTERRDIRECTIVE');
 11>   end;
 12>   /
package body testErrDirective is
  procedure run is
  begin
    dbms_output.put_line('Beginning test run...');

ORA-06550: line 5, column 3:
PLS-00179: $ERROR: Oh No! There's no code at line 6 in

PL/SQL procedure successfully completed.

小さくて高速なランタイムコード

 条件付きコンパイルは、使いやすくて幅広い目的に利用できます。ここで紹介した条件付きコンパイルの使い方は、ごく基本的なものにすぎません。例えば、顧客ごとにマスターコードをカスタマイズするような使い方もできます。個別にライセンスされる機能をメインコード本体に挿入し、ライセンスを受けていない顧客にはFALSEに設定したccflagで機能を隠すことができます。

 条件付きコンパイルは、少なくとも、大量のif v_debug=true then... else...呼び出しがパフォーマンスに与える悪影響を懸念してきた開発者の悩みを解決します。条件付きコンパイルを使ってこれらの呼び出しを運用コードから完全に消し去り、同時に将来のデバッグのためにデバッグフレームワークを残しておくことができます。

 小さくて高速なランタイムコードの恩恵を得るために、ぜひともこの応用範囲の広い新機能を今すぐ使い始めてください。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Natalka Roshak(Natalka Roshak)

カナダのオンタリオ州在住のデータベース管理者、アナリスト、およびアーキテクト。toolkit.rdbms-insight.comにも記事を執筆している。連絡先はwww.rdbms-insight.com/contact.php

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/647 2010/01/05 11:05

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー