Java のストアード・プロシージャーおよび UDF は、他のプログラミング言語と同じように作成し、使用できます。 Java コードを作成する際に知っている必要のある、プログラミングに関する考慮事項があります (Java での関数定義を参照)。 Java ストアード・プロシージャーおよび UDF を登録する 必要もあります。ストアード・プロシージャーを登録する方法の詳細については、 ストアード・プロシージャーを参照してください。 UDF を登録する方法の詳細については、 SQL 解説書 の CREATE FUNCTION ステートメントを参照してください。
サーバー上で UDF およびストアード・プロシージャーを実行するため、 DB2 は JVM を呼び出します。データベースを始動する前に、 DB2 サーバーに適切な Java 開発キット (JDK) または Java ランタイム環境を導入し、構成するようにしてください。
JVM の実行時ライブラリーは、システム探索パスで使用可能になっていなければなりません (PATH または LIBPATH または LD_LIBRARY_PATH、および CLASSPATH)。 Java 環境設定の詳細については、 アプリケーション構築の手引き を参照してください。
DB2 は、Java UDF またはストアード・プロシージャーが最初に呼び出された時に、 JVM をロードまたは開始します。 NOT FENCED を使用した UDF およびストアード・プロシージャーの場合、 DB2 はデータベース・インスタンスにつき 1 回 JVM をロードし、データベース・エンジンのアドレス空間内部で最善のパフォーマンスになるように実行します。 FENCED を使用した UDF の場合、 DB2 は db2udf プロセス内でまったく別の JVM を使用します。同様に、FENCED を使用したストアード・プロシージャーは、 db2dari プロセス内でまったく別の JVM を使用します。どの場合にも、JVM は組み込み処理が終了するまでロードされたままです。
注: | ローカル・クライアントのあるデータベース・サーバーのノード・タイプを実行している場合、 MAXDARI maxdari データベース・マネージャー 構成パラメーターをゼロ以外の値に設定してから、 Java ストアード・プロシージャーを呼び出す必要があります。 |
sqllib/samples/java ディレクトリーで提供されている Java ストアード・プロシージャーの例を調べることができます。 DB2 に含まれているサンプル・プログラムのリストについては、 付録 B, サンプル・プログラムを参照してください。
ストアード・プロシージャーまたは UDF をインプリメントするのに使用するすべての Java クラス・ファイルは、データベースにインストールした JAR ファイルか、またはオペレーティング・システムの正しいストアード・プロシージャーまたは UDF パスに常駐する必要があることに注意してください (Java クラスを置く場所を参照)。
注: | 混合コード・ページのデータベース・サーバーでは、 Java ユーザー定義関数およびストアード・プロシージャーは、 CLOB タイプ引き数を使用できません。なぜなら、ラージ混合コード・ページ・ストリングの文字境界へのランダム・アクセスがインプリメントされていないためです。 SBCS データベースの場合は、すべての LOB タイプが完全にサポートされます。一方、混合データベースの場合は、 BLOB および DBCLOB タイプがサポートされます。対処方法として、混合データベース・システムで実行するアプリケーションは、 CLOB 引き数を DBCLOB、LONG VARGRAPHIC、または LONG VARCHAR タイプに変換しなければなりません。 UDF の場合は、CAST 演算子を使用してこれを実行できます。 |
個々の Java クラス・ファイルをストアード・プロシージャーおよび UDF に使用するか、またはクラス・ファイルを JAR ファイルに収集してからデータベースにその JAR ファイルをインストールするかを選択できます。 JAR ファイルを使用することにした場合には、 Java ストアード・プロシージャーおよび UDF で詳しい指示を参照してください。
注: | Java ルーチン・クラス・ファイルを更新または置換する場合には、 CALL SQLJ.REFRESH_CLASSES() ステートメントを発行して、 DB2 が更新されたクラスをロードできるようにする必要があります。 CALL SQLJ.REFRESH_CLASSES() について詳しくは、 Java ルーチン・クラスの更新を参照してください。 |
DB2 がストアード・プロシージャーおよび UDF を検出し、使用できるようにするには、該当するクラス・ファイルを関数ディレクトリー に保管する必要があります。これは、ご使用のオペレーティング・システムに以下のように定義されたディレクトリーです。
たとえば、DB2 が C:\sqllib ディレクトリーにインストールされており、 DB2INSTPROF レジストリー設定が指定されていない Windows NT Server の関数ディレクトリーは、次のようになります。
C:\sqllib\function
個々のクラス・ファイルを使用することにした場合には、クラス・ファイルをご使用のオペレーティング・システムに該当するディレクトリーに保管する必要があります。 Java パッケージの一部分としてクラスを宣言した場合、関数ディレクトリーの下に対応するサブディレクトリーを作成し、そこにファイルを置いてください。たとえば、Linux システム用のクラス ibm.tests.test1 を作成する場合、対応する Java バイトコード・ファイル (test1.class) は sqllib/function/ibm/tests に保管してください。
DB2 を起動する JVM は、Java ファイルを見つけるのに、 CLASSPATH 環境変数を使用します。 DB2 は、関数ディレクトリーおよび sqllib/java/db2java.zip を CLASSPATH 設定の前に追加します。
JVM が Java クラス・ファイルを検索できるように環境を設定するには、 jdk11_path 構成パラメーターを設定してください。そうしない場合、省略時値が使用されます。また、java_heap_sz 構成パラメーターを設定して、アプリケーションのためにヒープ・サイズを増やす必要があります。構成パラメーターの詳細については、 管理の手引き を参照してください。
Java ルーチン・クラスを更新する場合には、 DB2 に新しいクラスをロードさせるため、 SQLJ.REFRESH_CLASSES() ステートメントも発行する必要があります。 Java ルーチン・クラスを更新した後に CALL SQLJ.REFRESH_CLASSES() ステートメントを発行しない場合、 DB2 は以前のバージョンのクラスを使用し続けます。 CALL SQLJ.REFRESH_CLASSES() ステートメントは、 FENCED ルーチンにのみ適用されます。 DB2 は、COMMIT または ROLLBACK が生じると、クラスを最新表示します。
注: | データベース・マネージャーを停止および再始動しないで、 NOT FENCED ルーチンを更新することができます。 |
DB2 は、 AIX または Windows NT Server 上でストアード・プロシージャーを実行する際に、 JDBC で作成されたストアード・プロシージャーを対話式にデバッグする機能を提供します。デバッグを呼び出す最も簡単な方法は、 DB2 ストアード・プロシージャー・ビルダーを使用することです。実行方法の詳細については、ストアード・プロシージャー・ビルダーのオンライン・ヘルプを参照してください。
この節には、以下の項目が含まれています。
db2set DB2ROUTINE_DEBUG=ON
デバッガーを呼び出すのにストアード・プロシージャー・ビルダーを使用しない場合には、次のコマンドでデバッグ表を作成します。
db2 -tf sqllib/misc/db2debug.ddl
注: | DB2 エンタープライズ拡張エディション ・システムでは、省略時ノードグループは USERSPACE1 表スペースでは IBMDEFAULTGROUP であり、システムに定義されたすべてのノードで構成されています。 DB2 エンタープライズ拡張エディション構成でストアード・プロシージャーのデバッグのパフォーマンスを改善するには、デバッグが発生する 1 つの調整プログラム・ノードがなければならず、そのノードだけを含むノードグループを定義しなければなりません。 |
ストアード・プロシージャー・クライアントから、次のコマンドでデバッガー・デーモンを開始します。
db2dbugd -qport=portno
ここで、portno は未使用の TCP/IP ポート番号です。値を指定しない場合には、デバッガーは省略時ポート番号として 8000 を使用します。 Windows 32 ビットのオペレーティング・システムでは、 DB2 フォルダーにあるデバッガー・デーモンのショートカットをクリックして、省略時ポート番号でデバッガーを開始することもできます。
デバッグ表には、デバッグされるストアード・プロシージャー、およびデバッグされるクライアント / サーバー環境についての情報が含まれます。 DBA または、INSERT、UPDATE、DELETE 特権のあるユーザーだけが、基礎表 DB2DBG.ROUTINE_DEBUG の値を直接操作することができます。しかし、DBA がさらに制限事項を追加しない限り、ユーザー視点 DB2DBG.ROUTINE_DEBUG_USER を介して、だれでも行を追加、更新、または削除できます。したがって、この節の続きでは、あるユーザーがユーザー視点を介して表に書き込むことを前提とします。
ストアード・プロシージャー・ビルダーを使用してデバッグを呼び出す場合には、デバッガー・ユーティリティーを使用してデバッグ表に書き込み、それを管理できます。そうでない場合、指定されたストアード・プロシージャーのデバッグ・サポートを使用可能にするには、 CLP から以下のコマンドを発行します。
DB2 INSERT INTO db2dbg.routine_debug_user (AUTHID, TYPE, ROUTINE_SCHEMA, SPECIFICNAME, DEBUG_ON, CLIENT_IPADDR) VALUES ('authid', 'S', 'schema', 'proc_name', 'Y', 'IP_num')
ここで、各パラメーターは以下のとおりです。
たとえば、ユーザーが USER1 で、デバッグするクライアントの IP アドレスが 123.234.111.222 のストアード・プロシージャー MySchema.myProc のデバッグを使用可能にするには、以下のコマンドをタイプします。
DB2 INSERT INTO db2dbg.routine_debug_user (AUTHID, TYPE, ROUTINE_SCHEMA, SPECIFICNAME, DEBUG_ON, CLIENT_IPADDR) VALUES ('USER1', 'S', 'MySchema', 'myProc', 'Y', '123.234.111.222')
ストアード・プロシージャーを除去する場合、このデバッグ情報はデバッグ表から自動的には削除されません。存在していないストアード・プロシージャーのデバッグ情報があっても、ご使用のデータベースまたはインスタンスに悪影響を与えることはありません。デバッグ表と DB2 カタログを同期化する場合は、デバッグ情報を手動で削除する必要があります。
デバッグ表を手動で作成した場合であっても、ストアード・プロシージャー・ビルダーで作成した場合であっても、そのデバッグ表には DB2DBG.ROUTINE_DEBUG という名前が付けられ、定義は以下のようになります。
表 32. DB2DBG.ROUTINE_DEBUG 表定義
列名 | データ・タイプ | 属性 | 説明 |
---|---|---|---|
AUTHID | VARCHAR(128) |
NOT NULL, DEFAULT USER | このストアード・プロシージャーのデバッグが実行されるアプリケーション authid。これはデータベースへの接続で提供されたユーザー ID です。 |
TYPE | CHAR(1) | NOT NULL | 有効な値: 'S' (Stored Procedure) |
ROUTINE_SCHEMA | VARCHAR(128) | NOT NULL | デバッグされるストアード・プロシージャーのスキーマ名。 |
SPECIFICNAME | VARCHAR(18) | NOT NULL | デバッグされるストアード・プロシージャーの固有名。 |
DEBUG_ON | CHAR(1) |
NOT NULL, DEFAULT 'N' | 有効な値:
|
CLIENT_IPADDR | VARCHAR(15) | NOT NULL | デバッグを実行するクライアントの IP アドレス。形式は nnn.nnn.nnn.nnn。 |
CLIENT_PORT | INTEGER |
NOT NULL, DEFAULT 8000 | デバッグ通信のポート。省略時値は 8000。 |
DEBUG_STARTN | INTEGER | NOT NULL | 使用されません。 |
DEBUG_STOPN | INTEGER | NOT NULL | 使用されません。 |
この表の基本キーは、AUTHID、TYPE、ROUTINE_SCHEMA、SPECIFICNAME です。
|
上記の手順を正常に実行できた場合、ストアード・プロシージャーを呼び出すと、デバッグ表に指定した IP アドレスのクライアントでデバッガーを起動します。
デバッガーでは、ソース・コードのステップスルー、変数の表示、およびソース・コードへのブレークポイントの設定を行えます。デバッガーの使用の詳細については、オンライン・ヘルプにあるデバッガーの資料を参照してください。
Java ストアード・プロシージャーおよび UDF (これらを Java ルーチン という) は、 DB2 カタログに登録する必要があります。 DB2 ユニバーサル・データベース バージョン 7 では、 Java ルーチンを登録および展開するために SQLJ ルーチン のコア仕様をサポートします。 CREATE PROCEDURE および CREATE FUNCTION ステートメントにある PARAMETER STYLE JAVA を使用して、 SQLJ ルーチンに準拠することを指定できます。
あるいは、DB2 では DB2 V5 および V5.2 PARAMETER STYLE DB2GENERAL ストアード・プロシージャーおよび UDF をサポートします。詳細については、付録 C, DB2DARI および DB2GENERAL ストアード・プロシージャーと UDF を参照してください。
Java 関数またはストアード・プロシージャーを登録するには、以下の手順に従ってください。
JAR ファイルをインストールする際には、 DB2 は JAR ファイルから Java クラス・ファイルを抽出し、システム・カタログにそれぞれのクラスを登録します。 DB2 は、JAR ファイルを関数ディレクトリーの jar/schema サブディレクトリーにコピーします。 DB2 は、JAR ファイルの新しいコピーに jar-id 文節で指定された名前を付けます。 DB2 インスタンスにすでにインストールされている JAR ファイルは直接変更しないでください。代わりに、 CALL SQLJ.REMOVE_JAR および CALL SQLJ.REPLACE_JAR コマンドを使用すると、インストールされた JAR ファイルを除去または置換できます。
DB2 インスタンスに JAR ファイルをインストールしたり、置換したりするには、コマンド行プロセッサーで以下のコマンド構文を使用できます。
(1) (2) >>-CALL-+-SQLJ.INSTALL_JAR-+---(--'--jar-url-------'--,--'--jar-id-------'--)--> '-SQLJ.REPLACE_JAR-' >--------------------------------------------------------------><
注:
注: | OS/2 および Windows 32 ビットのオペレーティング・システムでは、 DB2 は DB2INSTPROF インスタンス固有の登録設定によって指定されたパスに JAR ファイルを保管します。 JAR ファイルをインスタンスに固有なものにするには、そのインスタンスの DB2INSTPROF に固有な値を指定する必要があります。 |
たとえば、 file:/home/db2inst/classes/ ディレクトリーにある Proc.jar ファイルを DB2 インスタンスにインストールするには、コマンド行プロセッサーから次のコマンドを出します。
CALL SQLJ.INSTALL_JAR('file:/home/db2inst/classes/Proc.jar' , 'myproc_jar')
SQL コマンドが今後 Procedure.jar ファイルを使用する際には、 myproc_jar という名前で参照します。 JAR ファイルをデータベースから削除するには、以下の構文の CALL REMOVE_JAR コマンドを使用します。
(1) >>-CALL-SQLJ.REMOVE_JAR----(--'--jar-id-------'--)-------------><
注:
データベースから JAR ファイル myProc_jar を除去するには、コマンド行プロセッサーに次のコマンドを入力します。
CALL SQLJ.REMOVE_JAR('myProc_jar')
Java ルーチンを作成するには、public クラスにある、対応する public static メソッドをコーディングする必要があります。また、throws SQLException 文節を使用して Java ルーチンを宣言しなければなりません。メソッドのシグニチャーおよび残りのメソッド宣言を、メソッド本体からの出力に対応するようにコーディングしてください。
呼び出し側のプログラムに値を戻さないメソッドを作成するには、メソッドが void を戻すように宣言し、メソッド本体に渡す必要のあるパラメーターをシグニチャーに含めます。単純な UDPATE を実行し、クライアント・アプリケーションに値を戻さないストアード・プロシージャーを、以下のように作成できます。
public class JavaExamples { public static void updateJob(String oldJob, String newJob) throws SQLException { Connection conn=DriverManager.getConnection("jdbc:ibm.db2.sample"); PreparedStatement stmt = conn.prepareStatement("UPDATE employee SET job = ? WHERE job = ?"); stmt.setString(1, newJob); stmt.setString(2, oldJob); stmt.executeUpdate(); conn.close(); return; } }
それぞれの SQL データ・タイプに対応する Java 戻りタイプで、単一値を戻す Java メソッドを宣言します (Java でサポートされている SQL データ・タイプを参照)。 SQL INTEGER 値を戻すスカラー UDF を以下のように作成します。
public class JavaExamples { public static int getDivision(String division) throws SQLException { if (division.equals("Corporate")) return 1; else if (division.equals("Eastern")) return 2; else if (division.equals("Midwest")) return 3; else if (division.equals("Western")) return 4; else return 5; } }
ストアード・プロシージャーとしてカタログされた Java メソッドは、 1 つまたは複数の値を戻します。また、複数の結果セットを戻す Java ストアード・プロシージャーを作成することもできます。 ストアード・プロシージャーからの結果セットの戻りを参照してください。あらかじめ決められた数の値を戻すメソッドをコーディングするには、戻りタイプ void を宣言し、メソッドのシグニチャーに出力のタイプを配列として含めます。指定されたしきい値より低い収入を得ている従業員のうち、年齢の高い順から 2 人の名前、勤続年数、および収入を戻すストアード・プロシージャーを作成するには、以下のようにします。
public Class JavaExamples { public static void lowSenioritySalary (String[] name1, int[] years1, BigDecimal[] salary1, String[] name2, int[] years2, BigDecimal[] salary2, Integer threshhold) throws SQLException { #sql iterator ByNames (String name, int years, BigDecimal salary); ByNames result; #sql result = {"SELECT name, years, salary FROM staff WHERE salary < :threshhold ORDER BY years DESC"}; if (result.next()) { name1[0] = result.name(); years1[0] = result.years(); salary1[0] = result.salary(); } else { name1[0] = "****"; return; } if (result.next()) { name2[0] = result.name(); years2[0] = result.years(); salary2[0] = result.salary(); } else { name2[0] = "****"; return; } } }