SQL Anywhere では、Java ストアドプロシージャおよび関数をサポートしています。Java ストアドプロシージャまたはファンクションの動作は、SQL ストアドプロシージャまたはファンクションと同じです。ただし、プロシージャまたはファンクションのコードは Java で記述され、その実行はデータベースサーバの外側 (つまり Java VM 環境内) で行われます。接続ごとに 1 つのインスタンスではなく、各データベースの Java VM に 1 つのインスタンスがあります。Java ストアドプロシージャは結果セットを返すことができます。
データベースでの Java のサポートを使用するためには、いくつかの前提条件があります。
Java Runtime Environment のコピーをデータベースサーバコンピュータにインストールする必要があります。
SQL Anywhere データベースサーバが Java 実行ファイル (Java VM) を検出できる必要があります。
Java をデータベースで使用するには、データベースサーバが Java 実行ファイルを検出して開始できることを確認してください。これは、次の文を実行して確認できます。
START EXTERNAL ENVIRONMENT JAVA; |
データベースサーバが Java を開始できない場合は、データベースサーバが Java 実行ファイルを検出できないことが問題の原因であると考えられます。この場合は、ALTER EXTERNAL ENVIRONMENT 文を実行して、Java 実行ファイルのロケーションを明示的に設定してください。実行ファイル名を必ず含めてください。
ALTER EXTERNAL ENVIRONMENT JAVA LOCATION 'java-path'; |
次に例を示します。
ALTER EXTERNAL ENVIRONMENT JAVA LOCATION 'c:\\jdk1.7.0\\jre\\bin\\java.exe'; |
次の SQL クエリを実行して、データベースサーバが使用する Java VM のロケーションを問い合わせることができます。
SELECT db_property('JAVAVM'); |
START EXTERNAL ENVIRONMENT JAVA 文は、データベースサーバが Java VM を開始できるかどうかを確認する以外で使用することはありません。通常、Java ストアドプロシージャまたはファンクションを呼び出すと、Java VM は自動的に開始されます。
これと同様に、Java のインスタンスを停止するために STOP EXTERNAL ENVIRONMENT JAVA 文を使用する必要もありません。インスタンスは、データベースへの接続がすべて切断されると自動的に停止します。ただし、Java をこれ以上使用することがなく、一部のリソースを解放する必要がある場合は、STOP EXTERNAL ENVIRONMENT JAVA 文によって Java VM の使用カウントを減分できます。
データベースサーバが Java VM 実行ファイルを開始できることを確認したら、次に必要な Java クラスコードをデータベースにインストールします。これは、INSTALL JAVA 文を使用して行います。たとえば、次の文を実行して Java クラスをファイルからデータベースにインストールできます。
INSTALL JAVA NEW FROM FILE 'java-class-file'; |
データベースには、Java JAR ファイルもインストールできます。
INSTALL JAVA NEW JAR 'jar-name' FROM FILE 'jar-file'; |
Java クラスは、次のようにして変数からインストールできます。
CREATE VARIABLE JavaClass LONG VARCHAR; SET JavaClass = xp_read_file('java-class-file') INSTALL JAVA NEW FROM JavaClass; |
Java JAR ファイルは、次のようにして変数からインストールできます。
CREATE VARIABLE JavaJar LONG VARCHAR; SET JavaJar = xp_read_file('jar-file') INSTALL JAVA NEW JAR 'jar-name' FROM JavaJar; |
Java クラスをデータベースから削除するには、次のように REMOVE JAVA 文を使用します。
REMOVE JAVA CLASS java-class |
Java JAR をデータベースから削除するには、次のように REMOVE JAVA 文を使用します。
REMOVE JAVA JAR 'jar-name' |
既存の Java クラスを変更するには、次のように INSTALL JAVA 文の UPDATE 句を使用します。
INSTALL JAVA UPDATE FROM FILE 'java-class-file' |
データベース内の既存の Java JAR ファイルを更新することもできます。
INSTALL JAVA UPDATE JAR 'jar-name' FROM FILE 'jar-file'; |
Java クラスは、次のようにして変数から更新できます。
CREATE VARIABLE JavaClass LONG VARCHAR; SET JavaClass = xp_read_file('java-class-file') INSTALL JAVA UPDATE FROM JavaClass; |
Java JAR ファイルは、次のようにして変数から更新できます。
CREATE VARIABLE JavaJar LONG VARCHAR; SET JavaJar = xp_read_file('jar-file') INSTALL JAVA UPDATE FROM JavaJar; |
Java クラスをデータベースにインストールしたら、次に Java メソッドへのインタフェースとなるストアドプロシージャおよび関数を作成できます。EXTERNAL NAME 文字列には、Java メソッドを呼び出し、OUT パラメータおよび戻り値を返すために必要な情報が含まれています。EXTERNAL NAME 句の LANGUAGE 属性には JAVA を指定する必要があります。EXTERNAL NAME 句のフォーマットは次のとおりです。
EXTERNAL NAME 'java-call' LANGUAGE JAVA
java-call : [package-name.]class-name.method-name method-signature
method-signature :
( [ field-descriptor, ... ] ) return-descriptor
field-descriptor と return-descriptor : Z | B | S | I | J | F | D | C | V | [descriptor | Lclass-name;
Java メソッドシグネチャは、パラメータの型と戻り値の型を簡潔に文字で表現したものです。パラメータの数がメソッドシグネチャに指定された数字よりも小さい場合は、この差が DYNAMIC RESULT SETS に指定された数と等しくなるようにします。また、プロシージャパラメータリストよりも多いメソッドシグネチャ内の各パラメータには、メソッドシグネチャ
[Ljava/sql/ResultSet;
が必要です。
field-descriptor と return-descriptor の意味は次のとおりです。
フィールドタイプ | Java データ型 |
---|---|
B | byte |
C | char |
D | double |
F | float |
I | int |
J | long |
L class-name; | クラス class-name のインスタンス。クラス名は、完全に修飾された名前で、ドットを / に置き換えたものとします。例:java/lang/String |
S | short |
V | void |
Z | Boolean |
[ | 配列の各次元ごとに 1 つ使用 |
例:
double some_method( boolean a, int b, java.math.BigDecimal c, byte [][] d, java.sql.ResultSet[] rs ) { } |
この例では、次のシグネチャを得られます。
'(ZILjava/math/BigDecimal;[[B[Ljava/sql/ResultSet;)D' |
次のプロシージャは、Java メソッドへのインタフェースを作成するものです。この Java メソッドはいかなる値も返しません (V)。
CREATE PROCEDURE insertfix() EXTERNAL NAME 'JDBCExample.InsertFixed()V' LANGUAGE JAVA; |
次のプロシージャは、String ([Ljava/lang/String;) 入力引数を持つ Java メソッドへのインタフェースを作成するものです。この Java メソッドはいかなる値も返しません (V)。
CREATE PROCEDURE InvoiceMain( IN arg1 CHAR(50) ) EXTERNAL NAME 'Invoice.main([Ljava/lang/String;)V' LANGUAGE JAVA; |
次のプロシージャは、Java メソッド Invoice.init へのインタフェースを作成するものです。この Java メソッドは、文字列引数 (Ljava/lang/String;)、double (D)、別の文字列引数 (Ljava/lang/String;)、別の double (D) を受け取り、値を返しません (V)。
CREATE PROCEDURE init( IN arg1 CHAR(50), IN arg2 DOUBLE, IN arg3 CHAR(50), IN arg4 DOUBLE) EXTERNAL NAME 'Invoice.init(Ljava/lang/String;DLjava/lang/String;D)V' LANGUAGE JAVA |
次に示す Java の例は、文字列を受け取り、それをデータベースサーバメッセージウィンドウに書き込む関数 main
を含んでいます。また、Java 文字列を返す関数 whoAreYou
も含んでいます。
import java.io.*; public class Hello { public static void main( String[] args ) { System.out.print( "Hello" ); for ( int i = 0; i < args.length; i++ ) System.out.print( " " + args[i] ); System.out.println(); } public static String whoAreYou() { return( "I am SQL Anywhere." ); } } |
上記の Java コードは、Hello.java ファイルにあり、Java コンパイラを使用してコンパイルします。生成されるクラスファイルは次のようにデータベースにロードされます。
INSTALL JAVA NEW FROM FILE 'Hello.class'; |
Hello
クラスの main
メソッドへのインタフェースとなるストアドプロシージャは、Interactive SQL を使用して次のように作成されます。
CREATE PROCEDURE HelloDemo( IN name LONG VARCHAR ) EXTERNAL NAME 'Hello.main([Ljava/lang/String;)V' LANGUAGE JAVA; |
main
の引数は java.lang.String の配列として記述されています。Interactive SQL で次の SQL 文を実行することでインタフェースをテストします。
CALL HelloDemo('SQL Anywhere'); |
メッセージは、データベースサーバメッセージウィンドウに表示されます。System.out への出力はすべてサーバメッセージウィンドウにリダイレクトされます。
Hello
クラスの whoAreYou
メソッドへのインタフェースとなる関数は、Interactive SQL を使用して次のように作成されます。
CREATE FUNCTION WhoAreYou() RETURNS LONG VARCHAR EXTERNAL NAME 'Hello.whoAreYou(V)Ljava/lang/String;' LANGUAGE JAVA; |
関数 whoAreYou
は java.lang.String を返すものとして記述されています。Interactive SQL で次の SQL 文を実行することでインタフェースをテストします。
SELECT WhoAreYou(); |
Interactive SQL の [結果] ウィンドウの応答を確認してください。
Java 外部環境が開始されなかった理由をトラブルシューティングする場合、つまり、Java 呼び出しが行われたときにアプリケーションが「メインスレッドが見つからない」というエラーを受け取った場合、DBA は次のことを確認する必要があります。
Java VM のビット数がデータベースサーバと異なる場合、VM と同じビット数のクライアントライブラリがデータベースサーバコンピュータにインストールされていることを確認します。
sajdbc4.jar 共有オブジェクトと dbjdbc16/libdbjdbc16 共有オブジェクトのソフトウェアビルドが同じであることを確認します。
データベースサーバコンピュータに複数の sajdbc4.jar がある場合は、すべて同じソフトウェアバージョンに同期されていることを確認します。
データベースサーバコンピュータが非常にビジーである場合、タイムアウトが原因でエラーがレポートされる可能性があります。
![]() |
DocCommentXchange で意見交換できます
|
Copyright © 2013, SAP AG or an SAP affiliate company. - SAP Sybase SQL Anywhere 16.0 |