メモ

普通(に、使えた試しがないのだが)Oracleの、プロシージャにJavaを使おうと思ったら、次の四つのどれかを選択することになる

  • ソースのままOracleへ格納して、Oracle内部でコンパイルしてもらう
    • loadjavaで.javaOracleへ登録する
    • sqlplusなどでcreate or replace java source を入力する方法
  • ローカルでコンパイルして、Oracleへ格納/登録する
    • loadjavaで.classをOracleへ登録する
    • sqlplusなどでcreate or replace java class を入力する方法

の、どれかを使うことになる。
上から順にこういう感じになる


Test.java
public class Test {
public static int kakeru(int a,int b){
return a * b;
}
}
これを、ローカルフォルダに保存する。
ソースのままOracleへ登録
loadjava -u scott/tiger -r Test.java
sqlplusなどから、次のSQLから呼び出せるFUNCTIONへ変換
create or replace function func_kakeru(a in number, b in number) return number
is LANGUAGE JAVA
NAME 'kakeru(int, int) return int';
/

    • sqlplusなどでcreate or replace java source を入力する方法


sqlplusで
connect scott/tiger
create or replace JAVA SOURCE named test_src
IS
public class Test {
public static int kakeru(int a,int b){
return a * b;
}
};
/
これでjavaのソースが登録される。あとは、上と同じように呼び出し用のFUNCTIONから呼び出せる
create or replace function func_kakeru(a in number, b in number) return number
is LANGUAGE JAVA
NAME 'kakeru(int, int) return int';
/

    • loadjavaで.classをOracleへ登録する


Test.java
public class Test {
public static int kakeru(int a,int b){
return a * b;
}
}
これを、ローカルフォルダに保存してコンパイルする。
javac Test.java
ただし、対象のOracleのバージョンによってJavaのバージョンが変わるので注意
8.1.7だと1.3相当(らしい、確信はない)
Test.classファイルをOracleに登録するには、コマンドプロンプトから次を打つ
loadjava -u scott/tiger -r -f -v Test.class (※引数は適当)
sqlplusで接続して、
select * from user_objects where object_type = 'JAVA CLASS'
で、登録されていることを確認する(STATUSがVALIDになっていること)
後は、やはり、呼び出し用のFUNCTIONにマッピングしてあげる
create or replace func_kakeru(a in number, b in number) return number
IS
is LANGUAGE JAVA
NAME 'kakeru(int, int) return int';
/


Test.javaを書いてコンパイル(省略)Test.classを作る
コマンドプロンプト
loadjava -u scott/tiger -r Test.class
sqlplusで接続して
select * from user_objects where object_type = 'JAVA CLASS'
で、登録されていることを確認する(STATUSがVALIDになっていること)
後は、やはり、呼び出し用のFUNCTIONにマッピングしてあげる
create or replace func_kakeru(a in number, b in number) return number
IS
is LANGUAGE JAVA
NAME 'kakeru(int, int) return int';
/
ふぅ、長いな、で、今日、初めて知ったこと

  • Oracle8.1.7.x.xxxだと、init.oraにあるJava_Pool_Sizeがデフォルトで0になっている

init.oraのJava_Pool_Size=20971520(20MB)ぐらいに設定して、再起動が必要
知らないと(Oracle上での)JAVA CLASSオブジェクトを操作するときに
ORA-04031:共有メモリーの4032バイトを割り当てできません("shared pool","unknown
object","joxlod: in ehe","ioc_allocate_pal")

とかいう、エラーが出て悩むことになる。
さらに、このときSGAのサイズを見ると


select pool,bytes
from v$sgastat
where name = 'free memory'
and pool='shared pool'
明らかに数十MB単位で空いてるのに!なぜ、4032byteを割り当てられない!
と、しばらく悩む羽目になる。。。。

  • init.oraのCOMPATIBLEの値を見ておくこと

javaを使うにはCOMPATIBLEが8.1.0.0以上じゃないと使えない(らしい)ので壮じゃない場合は8.1.0.0以上の値に直して再起動すること。

  • JAVAの実行には権限が必要

grant文で権限付与はできないことに、注意。
dbms_javaパッケージのgrant_permissionプロシージャで権限付与を行う

  • 削除方法に注意が必要

loadjavaで登録した場合はdropjavaを使う
ソースで登録した場合の削除
drop java source "TEST_SRC"
登録の際にNAMEで指定した名前を大文字でダブルクォーテーションで囲わないとエラーになる。
classで登録した場合の削除
drop java class "Test"
登録の際に指定したクラス名を登録の際に入れた名前でダブルクォーテーションで囲わないとエラーになる




と、長々と一気に書いてみた。細かいところで間違いはあるかもしれないが、大体のイメージはこれ見たら思い出せるだろ>俺。