8.1 トップレベルからのJavaのコール
SQLのCALL
文を使用すると、トップレベルで公開されたJavaメソッドを、PL/SQLパッケージまたはSQLオブジェクト型でコールできます。SQL*Plusでは、次の構文を使用してCALL
文を対話形式で実行できます。
CALL [schema_name.][{package_name | object_type_name}][@dblink_name] { procedure_name ([param[, param]...]) | function_name ([param[, param]...]) INTO :host_variable};
param
は次の構文で表されます。
{literal | :host_variable}
ホスト変数は、ホスト環境で宣言された変数です。このホスト変数には接頭辞としてコロンを付ける必要があります。次の例は、同じCALL
文ではホスト変数を2度使用できないこと、およびパラメータのないサブプログラムは空のパラメータ・リストを使用してコールする必要があることを示しています。
CALL swap(:x, :x); -- illegal, duplicate host variables CALL balance() INTO :current_balance; -- () required
この項の内容は次のとおりです。
8.1.1 出力のリダイレクト
サーバーでのデフォルトの出力デバイスは、ユーザー・スクリーンではなくトレース・ファイルです。このため、System.out
およびSystem.err
は、現行のトレース・ファイルに出力されます。出力をSQL*Plusテキスト・バッファにリダイレクトするには、次のようにDBMS_JAVA
パッケージのset_output()
プロシージャをコールする必要があります。
SQL> SET SERVEROUTPUT ON SQL> CALL dbms_java.set_output(2000);
最小バッファ・サイズは2,000バイト(デフォルト・サイズ)で、最大バッファ・サイズは1,000,000バイトです。次の例では、バッファ・サイズを5,000バイトに増やしています。
SQL> SET SERVEROUTPUT ON SIZE 5000 SQL> CALL dbms_java.set_output(5000);
出力はストアド・プロシージャの終了時に表示されます。
8.1.2 トップレベルからのJavaストアド・プロシージャのコールの例
例8-1 簡単なJDBCストアド・プロシージャ
次の例にあるmain()
メソッドは、データベース表の名前(employees
など)、および条件(salary > 1500
など)を指定するオプションのWHERE
句を受け入れます。条件を省略した場合、メソッドは表からすべての行を削除し、条件を指定した場合は、その条件を満たす行のみを削除します。
import java.sql.*; import oracle.jdbc.*; public class Deleter { public static void main (String[] args) throws SQLException { Connection conn = DriverManager.getConnection("jdbc:default:connection:"); String sql = "DELETE FROM " + args[0]; if (args.length > 1) sql += " WHERE " + args[1]; try { Statement stmt = conn.createStatement(); stmt.executeUpdate(sql); stmt.close(); } catch (SQLException e) { System.err.println(e.getMessage()); } } }
main()
メソッドには、1つまたは2つの引数を指定できます。通常は、DEFAULT
句を使用して、PL/SQLサブプログラムに渡す引数の数を変更します。ただし、この句はコール仕様では使用できません。そのため、次のように2つのパッケージ・プロシージャをオーバーロードする必要があります。
CREATE OR REPLACE PACKAGE pkg AS PROCEDURE delete_rows (table_name VARCHAR2); PROCEDURE delete_rows (table_name VARCHAR2, condition VARCHAR2); END; CREATE OR REPLACE PACKAGE BODY pkg AS PROCEDURE delete_rows (table_name VARCHAR2) AS LANGUAGE JAVA NAME 'Deleter.main(java.lang.String[])'; PROCEDURE delete_rows (table_name VARCHAR2, condition VARCHAR2) AS LANGUAGE JAVA NAME 'Deleter.main(java.lang.String[])'; END;
これで、次のようにdelete_rows
プロシージャをコールできます。
SQL> CALL pkg.delete_rows('employees', 'salary > 1500'); Call completed. SQL> SELECT first_name, salary FROM employees; FIRST_NAME SALARY --------- -------- SMITH 800 WARD 1250 MARTIN 1250 TURNER 1500 ADAMS 1100 JAMES 950 MILLER 1300 7 rows selected.
注意:
トップレベルのプロシージャはオーバーロードできません。
例8-2 フィボナッチ数列
次のJavaクラスの実行可能ファイルがOracle Databaseに格納されているとします。
public class Fibonacci { public static int fib (int n) { if (n == 1 || n == 2) return 1; else return fib(n - 1) + fib(n - 2); } }
Fibonacci
クラスにはfib()
という名前のメソッドが1つあり、このメソッドはn番目のフィボナッチ数を戻します。フィボナッチ数列(1、1、2、3、5、8、13、21、...)は、再帰的です。数列の各項目(2番目の項目より後)は、直前の2つの項目の合計値です。fib()
は値を戻すため、次のようにファンクションとして公開する必要があります。
CREATE OR REPLACE FUNCTION fib (n NUMBER) RETURN NUMBER AS LANGUAGE JAVA NAME 'Fibonacci.fib(int) return int';
次に、2つのSQL*Plusホスト変数を宣言し、最初の変数を初期化します。
SQL> VARIABLE n NUMBER SQL> VARIABLE f NUMBER SQL> EXECUTE :n := 7; PL/SQL procedure successfully completed.
これで、fib()
ファンクションをコールできます。CALL
文では、ホスト変数に接頭辞としてコロンを付ける必要があります。このファンクションは次のようにコールできます。
SQL> CALL fib(:n) INTO :f; Call completed. SQL> PRINT f F ---------- 13