読者です 読者をやめる 読者になる 読者になる

「Oracle」Javaストアド・プロシージャ使ってみた

Oracle

Oracle Database に Java のクラスなんかを格納して、PL/SQL からそのクラスのメソッドとかを呼び出せる「Javaストアド・プロシージャ」なるものがあるらしい。
簡単に触ってみたので、その時のメモ。

[ 環境情報 ]
CentOS 5.5
Oracle Database 11g R2

1. まずは .class ファイルを作成する

class Test {
  public static String hello() {
    return "hello !!";
  }

  public static String hello2(String name) {
    return "hello " + name + " !!";
  }
}

※ 今回は "/home/oracle/java" ディレクトリに作成してます。

コンパイルしておく

javac -target 1.5 Test.java

※ ちなみに "-target 1.5" をつけないと、以下のエラーが発生する。
Oracle JVM は、J2SE 5.0 系ってことなんですかね。確認してないけど、たぶんそうなんだろう・・・
-----
行1でエラーが発生しました。:
ORA-29516: Auroraアサーションでエラーが発生しました: Assertion failure ateox.c:359
Uncaught exception System error: java/lang/UnsupportedClassVersionError
ORA-06512: "TEST.HELLO_1F", 行1
ORA-06512: 行2
-----

2. .class ファイルを Oracle Database に登録する

CREATE DIRECTORY java_dir AS '/home/oracle/java';
CREATE OR REPLACE JAVA CLASS USING BFILE (java_dir, 'Test.class')
/

3. Java メソッドを呼び出すストアドファンクションを作成する
* hello() を呼び出す

CREATE OR REPLACE FUNCTION hello RETURN VARCHAR2 AS LANGUAGE JAVA NAME 'Test.hello() return java.lang.String';
/

* hello2() を呼び出す

CREATE OR REPLACE FUNCTION hello2(name IN VARCHAR2) RETURN VARCHAR2 AS LANGUAGE JAVA NAME 'Test.hello2(java.lang.String) return java.lang.String';
/

上記でやることは完了。あとは、以下のコマンドで作成したストアドファンクションを実行してみてください。

SET SERVEROUTPUT ON
BEGIN
DBMS_OUTPUT.PUT_LINE(hello);
DBMS_OUTPUT.PUT_LINE(hello2('hoge'));
END;
/

以下の出力が得られるはず。

hello !!
hello hoge !!


.class ファイルの登録には "loadjava" を使う方法もあるみたいですが、これはまた興味が出たらやります。


ドキュメントは、以下あたりですね。

Javaストアド・プロシージャの開発
http://docs.oracle.com/cd/E16338_01/java.112/b56280/chfive.htm

Javaストアド・プロシージャのアプリケーションの例
http://docs.oracle.com/cd/E16338_01/java.112/b56280/cheight.htm

・CREATE JAVA
http://docs.oracle.com/cd/E16338_01/server.112/b56299/statements_5014.htm

・[Chapter 1] 1.19 Java Language Integration
http://docstore.mik.ua/orelly/oracle/langpkt/ch01_19.htm
↑のオライリーのやつを一番参考にしました・・・

以上です。


タイトルとは関係ない内容だけど、一応、残しておく。

■ ストアドプロシージャ等のエラーを確認するコマンド

show error

■ 引数のないストアドファンクション
"hello()" ではなく、"hello" と書くらしい。知らんかった・・・