Oracle JVMは、次世代の企業規模のアプリケーションを低コストで作成するために必要な機能をすべて備えています。最も重要な機能は、ストアド・プロシージャのサポートです。ストアド・プロシージャを使用すると、ビジネス・ロジックをサーバー・レベルで実装できるため、アプリケーションのパフォーマンス、スケーラビリティおよびセキュリティが向上します。
この章の内容は、次のとおりです。
ストアド・プロシージャは、SQLに対して公開され、一般的に使用できるようにデータベースに格納されるJavaメソッドです。Javaメソッドを公開するには、Javaメソッド名、パラメータ・タイプおよび戻り型を、対応するSQLにマップするコール仕様を記述します。
別の実行レイヤーが追加されるラッパーとは異なり、コール仕様では、Javaメソッドの存在が公開されます。したがって、コール仕様を使用してメソッドをコールすると、ランタイム・システムによって、最小限のオーバーヘッドでコールがディスパッチされます。
ストアド・プロシージャは、クライアント・アプリケーションからコールされると、引数を受け入れ、Javaクラスを参照し、Javaの結果値を戻すことができます。
図5-1では、様々なアプリケーションからコールされているストアド・プロシージャを示しています。
グラフィカル・ユーザー・インタフェース(GUI)のメソッドを除いて、Oracle JVMは、すべてのJavaメソッドをストアド・プロシージャとして実行できます。ランタイム・コンテキストには、次のものが含まれます。
ファンクションとプロシージャは、一連の文をカプセル化した名前付きのブロックです。これらは、モジュール化されたメンテナンスが容易なアプリケーションを作成するために使用できる構成単位となります。
一般的に、プロシージャは処理の実行に使用し、ファンクションは値の計算に使用します。したがって、戻り値がvoid
のJavaメソッドの場合は、プロシージャのコール仕様を使用し、値を戻すメソッドの場合は、ファンクションのコール仕様を使用します。
トップレベルおよびパッケージレベルのPL/SQLファンクションおよびプロシージャのみをコール仕様として使用できます。SQLのCREATE FUNCTION
、CREATE 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ストアド・プロシージャは、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 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
)が出力されます。
loadjava
ツールを使用すると、Javaのソース、クラスおよびリソース・ファイルをOracle Databaseインスタンスにロードでき、これらはJavaスキーマ・オブジェクトとして格納されます。loadjava
ツールはコマンドラインまたはアプリケーションから実行でき、リゾルバなどいくつかのオプションを指定できます。
次の例では、loadjava
ツールがデフォルトのJDBC OCIドライバを使用してデータベースに接続します。ユーザー名とパスワードを指定する必要があります。デフォルトでは、クラスOscar
はユーザーのログインするスキーマ(この場合はscott
)にロードされます。
$ loadjava -user scott Oscar.class
Password: password
quote()
メソッドをコールすると、サーバーはリゾルバを使用して、String
などのサポート・クラスを検索します。この場合はデフォルトのリゾルバが使用されます。デフォルトのリゾルバは最初に現行スキーマ内、次に、すべてのコアなJavaクラス・ライブラリが常駐しているSYS
スキーマ内を検索します。必要に応じて、別のリゾルバを指定できます。
SQLまたはJDBCからコール可能な各Javaメソッドに対して、メソッドのトップレベルのエントリ・ポイントをOracle Databaseに公開するコール仕様を記述する必要があります。通常、必要となるコール仕様は少数です。必要な場合は、Oracle JDeveloperを使用してこれらのコール仕様を生成できます。
次のSQL*Plusの例では、データベースに接続した後、quote()
メソッド用のトップレベルのコール仕様を定義します。
SQL> connect scott
Enter password: password
SQL> CREATE FUNCTION oscar_quote RETURN VARCHAR2
2 AS LANGUAGE JAVA
3 NAME 'Oscar.quote() return java.lang.String';
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
ツールを使用してコールすることもできます。