ヘッダーをスキップ
Oracle® Database Java開発者ガイド
12cリリース1 (12.1)
B72466-05
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

5 Javaストアド・プロシージャの開発

Oracle JVMは、次世代の企業規模のアプリケーションを低コストで作成するために必要な機能をすべて備えています。最も重要な機能は、ストアド・プロシージャのサポートです。ストアド・プロシージャを使用すると、ビジネス・ロジックをサーバー・レベルで実装できるため、アプリケーションのパフォーマンス、スケーラビリティおよびセキュリティが向上します。

この章の内容は、次のとおりです。

ストアド・プロシージャとランタイム・コンテキスト

ストアド・プロシージャは、SQLに対して公開され、一般的に使用できるようにデータベースに格納されるJavaメソッドです。Javaメソッドを公開するには、Javaメソッド名、パラメータ・タイプおよび戻り型を、対応するSQLにマップするコール仕様を記述します。

別の実行レイヤーが追加されるラッパーとは異なり、コール仕様では、Javaメソッドの存在が公開されます。したがって、コール仕様を使用してメソッドをコールすると、ランタイム・システムによって、最小限のオーバーヘッドでコールがディスパッチされます。

ストアド・プロシージャは、クライアント・アプリケーションからコールされると、引数を受け入れ、Javaクラスを参照し、Javaの結果値を戻すことができます。

図5-1では、様々なアプリケーションからコールされているストアド・プロシージャを示しています。

図5-1 ストアド・プロシージャのコール

図5-1の説明が続きます
「図5-1 ストアド・プロシージャのコール」の説明

グラフィカル・ユーザー・インタフェース(GUI)のメソッドを除いて、Oracle JVMは、すべてのJavaメソッドをストアド・プロシージャとして実行できます。ランタイム・コンテキストには、次のものが含まれます。

ファンクションおよびプロシージャ

ファンクションとプロシージャは、一連の文をカプセル化した名前付きのブロックです。これらは、モジュール化されたメンテナンスが容易なアプリケーションを作成するために使用できる構成単位となります。

一般的に、プロシージャは処理の実行に使用し、ファンクションは値の計算に使用します。したがって、戻り値がvoidのJavaメソッドの場合は、プロシージャのコール仕様を使用し、値を戻すメソッドの場合は、ファンクションのコール仕様を使用します。

トップレベルおよびパッケージレベルのPL/SQLファンクションおよびプロシージャのみをコール仕様として使用できます。SQLのCREATE FUNCTIONCREATE PROCEDUREまたはCREATE PACKAGE文を使用してファンクションとプロシージャを定義すると、これらはデータベースに格納され、一般的に使用可能になります。

ファンクションおよびプロシージャとして公開されたJavaメソッドは、明示的に起動する必要があります。これらのメソッドには引数を指定でき、次の文やプログラムからコール可能です。

  • SQLデータ操作言語(DML)文

  • SQLのCALL

  • PL/SQLのブロック、サブプログラムおよびパッケージ

データベース・トリガー

データベース・トリガーは、特定の表またはビューに関連付けられたストアド・プロシージャです。指定されたDML操作で表またはビューが変更されるたびに、Oracle Databaseによってトリガーが自動的にコールされます。

トリガーは次の3つの部分で構成されています。

  • トリガー・イベント(通常はDML操作)

  • オプションのトリガー制約

  • トリガー・アクション

イベントが発生すると、トリガーがコールされます。トリガーのCALL文によって、Javaメソッドがそのメソッドのコール仕様を使用してコールされてアクションが実行されます。

データベース・トリガーは、複雑なビジネス・ルールの実施、列値の自動取得、無効なトランザクションの防止、イベントの透過的な記録、トランザクションの監査および統計情報の収集に使用されます。

オブジェクト・リレーショナル・メソッド

SQLオブジェクト型は、属性と呼ばれる一連の変数と、メソッドと呼ばれる一連の操作をカプセル化したユーザー定義のコンポジット・データ型で、Javaで作成できます。一連の属性で構成されたデータ構造は、publicです。ただし、プログラミングの慣例として、アプリケーションでこれらの属性が直接操作されず、提供される一連のメソッドが使用されることを確認する必要があります。

SQLオブジェクト型として、実在のオブジェクトに対応する抽象テンプレートを作成できます。テンプレートでは、オブジェクトがアプリケーション環境で必要とする属性とメソッドのみを指定します。実行時(データ構造に値を割り当てるとき)に、オブジェクト型のインスタンスを作成します。インスタンスは必要な数だけ作成できます。

通常、オブジェクト型は、発注書などのビジネス・エンティティに対応します。項目の変数値を格納するには、オブジェクト型ではVARRAYまたはネストした表(あるいはその両方)を使用できます。

たとえば、発注書のオブジェクト型に明細項目の変数値を格納できます。

ストアド・プロシージャの利点

ストアド・プロシージャにはいくつかの利点があります。この項では次の利点について説明します。

パフォーマンス

ストアド・プロシージャは、一度コンパイルされて実行可能な形式で格納されています。そのため、プロシージャ・コールが迅速かつ効率的に処理されます。実行可能コードは自動的にキャッシュされ、ユーザー間で共有されます。この結果、メモリー要件や起動時のオーバーヘッドが低減します。

SQL文をグループ化することによって、ストアド・プロシージャではそれらを1回のコールで処理できます。この結果、ネットワークの通信量が減少し、ラウンドトリップの応答時間が短縮されます。

また、ストアド・プロシージャを使用すると、サーバーのコンピューティング資源を利用できます。たとえば、計算専用プロシージャをクライアントからサーバーに移動すると、サーバーでより高速に実行できます。ストアド・ファンクションにより、サーバー内でアプリケーション・ロジックが実行されるため、パフォーマンスが向上します。

生産性と使いやすさ

共通のストアド・プロシージャのセットの周囲にアプリケーションを設計することによって、冗長なコーディングを回避し、生産性を向上させることができます。さらに、ストアド・プロシージャを使用するとデータベースの機能を拡張できます。

ストアド・プロシージャの作成には、希望に応じてJava統合開発環境(IDE)を使用できます。これらのストアド・プロシージャは、Java Database Connectivity(JDBC)などの標準Javaインタフェース、またはSQLJ、Oracle Call Interface(OCI)、Pro*C/C++およびJDeveloperなどのプログラム・インタフェースや開発ツールによりコールできます。

このようなストアド・プロシージャへの広範囲にわたるアクセス方法によって、アプリケーション間でビジネス・ロジックを共有できます。たとえば、ビジネス・ルールを実装するストアド・プロシージャは、様々なクライアント・サイド・アプリケーションからコールできるため、そのすべてのアプリケーションがビジネス・ルールを共有できます。また、サーバーのJava機能を利用する一方で、任意のプログラム・インタフェース用のアプリケーションを引き続き作成できます。

スケーラビリティ

データベースのJavaは、Oracleデータベースのスケーラブルなセッション・モデルを継承します。ストアド・プロシージャでは、サーバー上のアプリケーション処理を独立することによってスケーラビリティが向上します。また、ストアド・プロシージャの依存性自動追跡機能は、スケーラブルなアプリケーションの開発に役立ちます。

メンテナンス性

妥当性チェックが実施されているストアド・プロシージャは、どのアプリケーションでも使用できます。ストアド・プロシージャの定義が変更された場合、影響を受けるのはそのプロシージャのみで、プロシージャをコールするアプリケーションには影響しません。このため、メンテナンスおよび拡張が容易になります。また、1つのプロシージャをサーバー上でメンテナンスする方が、様々なクライアント・コンピュータ上のコピーをメンテナンスするより簡単です。

相互運用性

Oracle Databaseで、JavaはJava言語仕様(JLS)に完全に準拠し、汎用のオブジェクト指向プログラミング言語の利点をすべて提供します。また、PL/SQLと同様に、JavaではOracleデータへのフル・アクセスが提供されています。そのため、PL/SQLで作成されるプロシージャはすべてJavaで作成できます。

Javaストアド・プロシージャはPL/SQLストアド・プロシージャによって補完されます。通常、プロシージャ型の拡張機能を必要とするSQLプログラマはPL/SQLを使用することが多く、Oracleデータに簡単にアクセスする必要があるJavaプログラマはJavaをよく使用します。

Oracle Databaseを使用すると、JavaとPL/SQL間の高度な相互運用性が実現します。Javaアプリケーションは埋込み型のJDBCドライバを使用してPL/SQLストアド・プロシージャをコールできます。一方、PL/SQLアプリケーションはJavaストアド・プロシージャを直接コールできます。

レプリケーション

Oracle Advanced Replicationを使用すると、ストアド・プロシージャをOracle Databaseのあるインスタンスから別のインスタンスにレプリケートできます。この機能により、ストアド・プロシージャを使用して基本的なビジネス・ルール・セットを実装できます。ストアド・プロシージャは、一度作成すると、レプリケートして、企業内の作業グループや支店に配布できます。この方法で、個々のサーバーではなく中央のサーバーでポリシーを改訂できます。

セキュリティ

セキュリティの範囲は広く、次のものが含まれます。

  • 接続に関するネットワーク・セキュリティ

  • オペレーティング・システム・リソースまたはJVM定義クラスやユーザー定義クラスのアクセス制御および実行制御

  • 外部ソースからインポートされたJARファイルのバイトコード検証。

Oracle Databaseでは、すべてのクラスがセキュアなデータベースにロードされるため、アントラステッドな状態になります。ユーザーがクラスおよびオペレーティング・システム・リソースにアクセスするには、適切なパーミッションが必要です。同様に、すべてのストアド・プロシージャは他のユーザーから保護されています。ストアド・プロシージャにアクセスする必要があるユーザーに、EXECUTEデータベース権限を付与できます。

また、ユーザーに対しては、定義者権限で実行されるストアド・プロシージャのみからOracleデータの操作を許可することによって、Oracleデータへのアクセスを制限できます。たとえば、データベースの表を更新するプロシージャへのアクセスは許可しても、その表自体へのアクセスは拒否することもできます。

Javaストアド・プロシージャの手順

Javaストアド・プロシージャは、PL/SQLストアド・プロシージャと同じ方法で実行できます。Javaストアド・プロシージャは、トリガーまたはSQL DMLコールの結果としてコールされることが一般的なため、通常はデータベース操作の結果として実行されます。Javaストアド・プロシージャをコールするには、コール仕様を使用して公開する必要があります。

Javaストアド・プロシージャをコールする前に、それらをOracle Databaseインスタンスにロードし、SQLに対して公開する必要があります。ロードと公開は別のタスクです。多くのJavaクラスは、他のJavaクラスからのみ参照されるため公開されることはありません。

Javaストアド・プロシージャを自動的にロードするには、loadjavaツールを使用します。これは、Javaのソース、クラスおよびリソース・ファイルを、システムによって生成されたデータベース表にロードし、次にSQLのCREATE JAVA {SOURCE | CLASS | RESOURCE}文を使用して、JavaファイルをOracle Databaseインスタンスにロードします。Javaファイルは、ファイル・システム、一般的なJava IDE、イントラネットまたはインターネットからアップロードできます。

Javaストアド・プロシージャを作成、ロードおよびコールする手順は、次のとおりです。


注意:

Javaストアド・プロシージャを手動でロードするには、CREATE JAVA文を使用できます。たとえば、SQL*Plusでは、CREATE JAVA CLASS文を使用して、ローカルのBFILEおよびLOB列からOracle DatabaseにJavaクラス・ファイルをロードできます。

手順1: Javaクラスの作成または再利用

任意のJava IDEを使用してクラスを作成するか、または必要に応じた既存のクラスを再利用します。Oracle Databaseでは、多数のJava開発ツールおよびクライアント・サイドのプログラム・インタフェースがサポートされます。たとえば、Oracle JVMでは、Oracle JDeveloper、Symantec Visual CafeおよびBorland JBuilderなどの一般的なJava IDEで開発されたプログラムを使用できます。

次の例では、publicクラスOscarを作成します。これには、Oscar Wildeの引用句を戻すquote()という単一のメソッドがあります。

public class Oscar
{
  // return a quotation from Oscar Wilde
  public static String quote()
  {
    return "I can resist everything except temptation.";
  }
}

クラスをOscar.javaとして保存します。Javaコンパイラを使用して、次のように、.javaファイルをクライアント・システム上でコンパイルします。

javac Oscar.java

コンパイラによって、Javaバイナリ・ファイル(この例の場合はOscar.class)が出力されます。

手順2: Javaクラスのロードおよび解決

loadjavaツールを使用すると、Javaのソース、クラスおよびリソース・ファイルをOracle Databaseインスタンスにロードでき、これらはJavaスキーマ・オブジェクトとして格納されます。loadjavaツールはコマンドラインまたはアプリケーションから実行でき、リゾルバなどいくつかのオプションを指定できます。

次の例では、loadjavaツールがデフォルトのJDBC OCIドライバを使用してデータベースに接続します。ユーザー名とパスワードを指定する必要があります。デフォルトでは、クラスOscarはユーザーのログインするスキーマ(この場合はHR)にロードされます。

$ loadjava -user HR Oscar.class
Password: password

quote()メソッドをコールすると、サーバーはリゾルバを使用して、Stringなどのサポート・クラスを検索します。この場合はデフォルトのリゾルバが使用されます。デフォルトのリゾルバは最初に現行スキーマ内、次に、すべてのコアなJavaクラス・ライブラリが常駐しているSYSスキーマ内を検索します。必要に応じて、別のリゾルバを指定できます。

手順3: Javaクラスの公開

SQLまたはJDBCからコール可能な各Javaメソッドに対して、メソッドのトップレベルのエントリ・ポイントをOracle Databaseに公開するコール仕様を記述する必要があります。通常、必要となるコール仕様は少数です。必要な場合は、Oracle JDeveloperを使用してこれらのコール仕様を生成できます。

次のSQL*Plusの例では、データベースに接続した後、quote()メソッド用のトップレベルのコール仕様を定義します。

SQL> connect HR
Enter password: password

SQL> CREATE FUNCTION oscar_quote RETURN VARCHAR2
2 AS LANGUAGE JAVA
3 NAME 'Oscar.quote() return java.lang.String';

手順4: ストアド・プロシージャのコール

Javaストアド・プロシージャは、JDBC、SQLJ、およびコール仕様にアクセスできるすべてのサード・パーティ言語からコールできます。SQLのCALL文を使用すると、トップレベル(たとえば、SQL*Plus)からストアド・プロシージャをコールできます。ストアド・プロシージャはデータベース・トリガーからもコールできます。

次の例では、SQL*Plusのホスト変数を宣言します。

SQL> VARIABLE theQuote VARCHAR2(50);

この後で、oscar_quote()ファンクションを次のようにコールします。

SQL> CALL oscar_quote() INTO :theQuote;

SQL> PRINT theQuote;

THEQUOTE
--------------------------------------------------
I can resist everything except temptation.

また、Javaクラスはojvmjavaツールを使用してコールすることもできます。


関連項目:

「ojvmjavaツール」

Javaストアド・プロシージャのデバッグ

Oracle Databaseには、Javaストアド・プロシージャをデバッグするためのJava Debug Wire Protocol (JDWP)インタフェースが用意されています。JDWPは、Java Development Kit (JDK) 1.4以上のバージョンでサポートされています。

JDWPインタフェースでサポートされているいくつかの機能を次に示します。

  • 接続のリスニング

  • デバッグ中の変数値の変更

  • 任意のJava式の評価(メソッド評価など)

  • 行上またはメソッド内でのブレークポイントの設定または解除

  • コードのステップ実行

  • フィールド・アクセスまたは変更ウォッチポイントの設定または解除


注意:

Oracle JDeveloperは、ユーザーが使いやすいようにこれらのデバッグ機能と統合されています。その他の独立系統合開発環境(IDE)ベンダーも、自社のデバッガをOracle Databaseと統合できます。

この項の内容は、次のとおりです。

Javaストアド・プロシージャのデバッグの前提条件

Javaストアド・プロシージャをデバッグする前に、次の前提条件が満たされていることを確認してください。

  • Javaコードをデータベースにデプロイする必要があり、オプションでデバッグ情報を使用してコンパイルできます。

  • データベース・ユーザー・アカウントが次の権限を持っている必要があります。

    DEBUG ANY PROCEDURE
    DEBUG CONNECT SESSION
    
  • 次のようにして、jdwp権限をアクセス制御リスト(ACL)に追加する必要があります。

          SQL> begin
          2    DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
          3      host => <host_name>,
          4      ace  => xs$ace_type(privilege_list => xs$name_list('jdwp'),
          5                          principal_name => <user_name>,
          6                          principal_type => xs_acl.ptype_db));
          7  end;
          8  /
    

関連項目:

アクセス制御リストへの権限の追加の詳細は、『Oracle Databaseセキュリティ・ガイド』を参照してください。

jdbデバッガを使用したJavaストアド・プロシージャのデバッグ

jdbセッションは、-listen <port>コマンドを使用して開始できます。この方法でセッションを開始した場合、jdbは実行中の仮想マシン(VM)が標準のコネクタを使用して指定のアドレスに接続するのを待機します。


注意:

Javaストアド・プロシージャのデバッグ中、jdbはJVMセッションを開始できず、VMによる接続を待機するのみです。

SQL*PlusなどのOracleクライアントを使用して、デバッガに接続するためのコマンドを発行します。どのクライアントを使用する場合でも、デバッガ接続コマンドを発行するセッションが、Javaストアド・プロシージャを実行するセッションと同じであることを確認する必要があります。たとえば、SQL*Plusを使用している場合は、次のコマンドを発行して、JDWPセッション用に指定したマシンおよびポートへのTCP/IP接続をオープンします。

EXEC DBMS_DEBUG_JDWP.CONNECT_TCP(<host_ip>, <port>)

デバッガが接続を受け入れた後、デバッガ・セッションのブレークポイントを発行し、OracleクライアントでJavaストアド・プロシージャを起動します。これで、デバッガは、指定した最初のブレークポイントで停止します。

JDeveloperを使用したJavaストアド・プロシージャのデバッグ

JDeveloperを使用して、Javaストアド・プロシージャおよびPL/SQLプログラムをシームレスにデバッグできます。PL/SQLプログラムおよびJavaストアド・プロシージャをローカルにデバッグする場合、デバッグを開始するためのコールはJDeveloperから直接行います。JDeveloperによってデバッグ対象のプログラム(デバッグ対象)が自動的に起動され、そのプログラムにデバッガがアタッチされます。

PL/SQLプログラムのリモート・デバッグおよびローカル・デバッグとJavaストアド・プロシージャの主な違いは、デバッグ・セッションの開始方法です。リモート・デバッグの場合は、SQL*PlusなどのOracleクライアント、DBMS_JOBパッケージを使用して作成されたジョブ、OCIプログラムまたはトリガー起動を使用して、デバッグ対象のプログラムを手動で起動する必要があります。その後、デバッグ対象のデータベース・プログラム(デバッグ対象)からJDeveloperデバッガへの接続を確立する必要があります。デバッグ対象プロセスが開始し、JDeveloperのデバッガがプロセスにアタッチされた後は、リモート・デバッグとローカル・デバッグの動作はよく似ています。


注意:

オプションで、デバッグの操作性を向上させるためにJITをオフにすることもできます。


関連項目:

JDeveloperを使用したJavaストアド・プロシージャのデバッグの詳細は、次のページを参照してください。

http://docs.oracle.com/cd/E16162_01/user.1112/e17455/dev_stored_proc.htm#BEJEJIHD