ヘッダーをスキップ
Oracle Database Java開発者ガイド
10gリリース2(10.2)
B19189-01
  目次へ
目次
索引へ
索引

前へ
前へ
次へ
次へ
 

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

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

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

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

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

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

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

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

ストアド・プロシージャのコール
画像の説明

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

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

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

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

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

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

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

  • SQLのCALL

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

5.1.2 データベース・トリガー

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

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

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

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

  • トリガー・アクション

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

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

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

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

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

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

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

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

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

5.2.1 パフォーマンス

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

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

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

5.2.2 生産性と使いやすさ

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

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

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

5.2.3 スケーラビリティ

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

共有サーバーの共有メモリー機能によって、Oracle Databaseでは、単一ノード上で10,000を超える同時ユーザーをサポートできます。スケーラビリティをさらに向上させるには、Oracle Net Services Connection Managerを使用してOracle Net Servicesの接続を多重化できます。

5.2.4 メンテナンス性

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

5.2.5 相互運用性

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ストアド・プロシージャを直接コールできます。

5.2.6 レプリケーション

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

5.2.7 セキュリティ

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

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

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

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

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

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

5.3 Javaストアド・プロシージャの構成

Javaストアド・プロシージャを実行するようにデータベースを構成するには、データベースを実行するモードを次のいずれかに決定する必要があります。

サーバー上でJavaストアド・プロシージャを実行するJava、SQLまたはPL/SQLのクライアントは、Oracle Net Services接続を介してデータベースに接続します。


関連項目:

『Oracle Database Net Services Administrator's Guide』

5.4 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クラス・ファイルをロードできます。

5.4.1 手順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)が出力されます。

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

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

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

$ loadjava -user scott/tiger Oscar.class

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

5.4.3 手順3: Javaクラスの公開

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

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

SQL> connect scott/tiger

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

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

Javaストアド・プロシージャは、SQLのDML文、PL/SQLブロックおよびPL/SQLサブプログラムからコールできます。 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.

5.4.5 手順5: ストアド・プロシージャのデバッグ(必要な場合)

ストアド・プロシージャのデバッグは必須です。Javaストアド・プロシージャは、別のコンピュータにあるサーバー上でリモートで実行されます。ただし、JDKデバッガ(jdb)はリモートのJavaプログラムをデバッグできません。そのため、データベースにロードする前にクライアント・コンピュータでストアド・プロシージャをデバッグする必要があります。