JDBC・Oracleストアドプロシージャのコール

 JDBCからOracleのストアドファンクションやストアドプロシージャを呼び出すこともできます。 この場合は、StatementやPreparedStatementクラスではなく、 CallableStatementというクラスを使います。 CallableStatementはPreparedStatementの派生クラスで、「?」 を使ったパラメータのバインドなどは全く同じやり方が通用します。
 Javaのコーディングの前に、まずPL/SQLでストアドファンクションを作ります。

create or replace function get_name_from_id1
(as_parts_id in varchar2) return varchar2 is
  ps_name	varchar2(60);
begin
  SELECT NAME INTO ps_name FROM PARTS
   WHERE PARTS_ID = as_parts_id;
  return ps_name;
exception
when NO_DATA_FOUND then
  return NULL;
end;
/

 同じようにストアドプロシージャも作ります。

create or replace procedure get_name_from_id2
(as_parts_id in varchar2, as_name out varchar2)
is
  ps_name varchar2(60);
begin
  SELECT NAME INTO ps_name FROM PARTS
   WHERE PARTS_ID = as_parts_id;
  as_name := ps_name;
exception
when NO_DATA_FOUND then
  as_name := NULL;
end;
/

 これらのストアドプログラムユニットをコールするJavaアプリケーションのソースコードは、 次のようになります。

import java.sql.*;

public class OciCallableTester {
  public static void main (String args []) {
    String s;
    try {
      // Oracle JDBC driverをロードします。
      DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());

      Connection conn =
	DriverManager.getConnection ("jdbc:oracle:thin:@eodb", "URANO", "URANO398");

      // ストアドファンクションを実行します。PL/SQLブロックの
      // BEGIN..ENDの代わりに{ }で囲みます。戻り値はパラメータで
      // 取得するために「?」を入れておきます。
      CallableStatement cstmt1 = conn.prepareCall(
        "{? = call get_name_from_id1(?)}"
      );
      // 戻り値の型を指定
      cstmt1.registerOutParameter(1, java.sql.Types.VARCHAR);
      // パラメータをセットして実行
      cstmt1.setString(2, "CP00014640");
      cstmt1.execute();
      // 結果の取得
      s = cstmt1.getString(1);
      System.out.println("get_name_from_id1 :" + s);
      cstmt1.close();

      // ストアドプロシージャを実行します。
      CallableStatement cstmt2 = conn.prepareCall(
        "{call get_name_from_id2(?, ?)}"
      );
      // 戻り値の型を指定
      cstmt2.registerOutParameter(2, java.sql.Types.VARCHAR);
      // パラメータをセットして実行
      cstmt2.setString(1, "CP00014648");
      cstmt2.execute();
      // 結果の取得
      s = cstmt2.getString(2);
      System.out.println("get_name_from_id2 :" + s);
      cstmt2.close();

      // データベースから切断して、完了。
      conn.close();
    } catch(SQLException ex){
      System.out.println("Ootto! Exception Caught: " + ex.getMessage());
      ex.printStackTrace();
    }
  }
}
// end.

 サンプルの通りということで詳細は省きます。 ストアドファンクションの戻り値やストアドプロシージャのOUT変数の値のデータ型を指定する registerOutParameterの記号定数は、 各ベンダのRDBMSのデータ型とJDBCのデータ型の間でマッピングが定められています。 まま、おおむね INTEGERVARCHAR のような普通の記号定数を使っておけばいいと思います。

 なお、ストアドプロシージャの仕様は、各RDBMS間で著しく差異があります。 例えばMySQLにはストアドプロシージャという機構自体がありませんし、 PostgreSQLにはストアドプロシージャはあります (通例「ユーザ定義関数」と呼ばれることの方が多いようです) が、 そのJDBCドライバにはCallableStatementはサポートされていません。 これはなぜかというと、PostgreSQLのユーザ定義関数を実行する構文にひみつがあります。 PostgreSQLでは、例えば、「get_name_from_id」というユーザ定義関数を実行するとき、

psql> SELECT GET_NAME_FROM_ID(4649)
CP0138504296

のような構文になります。つまり、ユーザ定義関数の実行をSELECT文で行うために、 CallableStatementは必要ないのです。

JDBC and Swing Top

(first uploaded 2001/01/08 last updated 2002/03/02, URANO398)

楽天モバイル[UNLIMITが今なら1円] ECナビでポインと Yahoo 楽天 LINEがデータ消費ゼロで月額500円〜!


無料ホームページ 無料のクレジットカード 海外格安航空券 解約手数料0円【あしたでんき】 海外旅行保険が無料! 海外ホテル