[Oracle] Java ストアドプロシージャの利用法 | Archive Redo Blog

Archive Redo Blog

DBエンジニアのあれこれ備忘録

OracleにはJava VMが実装されており、Javaプログラムをデータベース上で動作させることができます。


JavaストアドプロシージャはOracleデータベース上へのJavaプログラムの実装形態の1つで、Oracleデータベース内に格納されたJavaクラスを指します。


このJavaクラス内に定義されているメソッドをSQLやPL/SQLから呼び出すことにより、様々な処理を行うことができるのです。


Javaストアドプロシージャを利用するとパフォーマンス、生産性、拡張性、メンテナンス性、セキュリティなどの面でメリットがありますが、SQLやPL/SQLでは不可能な特殊な処理を行いたい場合などに利用するというのがよくあるパターンでしょう。

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

Javaストアドプロシージャの実装は、普通のストアドプロシージャよりもちょっとややこしいです。


以下に外部コマンドを実行するためのJavaストアドプロシージャの例を示してみます。

1.Javaクラスの作成
まず、Javaストアドプロシージャとして利用するJavaクラスのコードを記述し、コンパイルしてクラスファイルを作成します。

public class CommandShell {
  public static int exec( String cmdStr ) {
    try {
      Runtime rt = Runtime.getRuntime();
      Process pc = rt.exec( cmdStr );
      int rc = pc.waitFor();
      return rc;
    } catch (Exception e) {
      e.printStackTrace();
      return 1;
    }
  }
}
2.JavaクラスのOracleへのロード

Javaクラスを作成したら、作成したクラスファイルをOracleにロードします。


その前に、Javaクラスを配置したディレクトリにアクセスできるようディレクトリを作成しておきます。

CREATE OR REPLACE DIRECTORY JAVA_CLASS_DIR AS 'C:\Oracle\admin\ORCL\src';

そして、CREATE JAVA文を実行してJavaクラスをOracleにロードします。

CREATE OR REPLACE JAVA CLASS USING BFILE (JAVA_CLASS_DIR, 'CommandShell.class');
3.メソッドのパブリッシュ

SQLからJavaストアドプロシージャを呼び出すためには、Javaメソッド名、パラメータの型、戻り値の型をSQLにマップするための呼び出しの仕様(コール・スペック)を定義する必要があります。


上記のメソッドを呼び出すコールスペックであれば以下のように記述します。

CREATE OR REPLACE FUNCTION EXEC_COMMAND_FUNC ( p_cmdstr VARCHAR2 ) RETURN NUMBER
  AS LANGUAGE JAVA
  NAME 'CommandShell.exec( java.lang.String ) return int';
4.セキュリティの設定

Javaストアドプロシージャ内でコマンドの実行やファイルの入出力などを行う場合は、実行ユーザーに対して適切な権限を付与する必要があります。


実行権限の付与はDBMS_JAVAパッケージのGRANT_PERMISSIONプロシージャで実行します。


例えばファイルの実行権限であれば以下のように記述します。

CALL dbms_java.grant_permission( 'SCOTT', 'SYS:java.io.FilePermission', '<<ALL FILES>>', 'execute' );
5.Javaストアドプロシージャの呼び出し方法

作成したJavaストアドプロシージャは、3.で定義したコールスペックを通常のプロシージャやファンクションと同じように呼び出すことによって実行します。


例えば、上記の手順で作成した外部コマンドを実行するためのJavaストアドプロシージャでDOSのDIRコマンドを実行し、結果をテキストファイルに書き出すなら以下のような感じで実行します。

DECLARE
  wk_return number(10);
BEGIN
  wk_return := EXEC_COMMAND_FUNC( 'CMD /C "DIR > dir.log"' );
END;


とまぁ、こんな手順でJavaストアドプロシージャを作成し実行できるというわけです。


手順はかなりまどろっこしいですが、これが使えればPL/SQLでできることの幅が格段に広がるので知っておいて損はありません。


ただ、逆に「そんな処理はPL/SQLではできません!」と突っぱねられなくなるので仕事は増えてしまうかも^^;


Javaストアドプロシージャの詳細についてはOracleのマニュアルや技術資料を参照のこと。




【関連エントリ】
[Oracle] Java ストアドプロシージャの利用法 2004/07/30
[Oracle] Java ストアドプロシージャで日本語ファイル名が扱えない 2004/12/27
[Oracle] loadjava ユーティリティが落ちる? 2006/06/29
[Oracle] Java ストアドプロシージャで Java クラス・ライブラリを使用する 2006/07/05
[Oracle] Java ストアドプロシージャで DLL を使用する際の注意点 2006/07/11