Java ストアド・プロシージャ

Java ストアド・プロシージャの作成の仕方を紹介してみたいと思います。


Java ストアド・プロシージャはJavaのクラスのメソッドとして実装されます。クラスの名前とメソッドは一致させる必要はなく、いくつかのストアド・プロシージャをひとつのクラスにまとめることも可能です。(むしろそちらの方がおすすめできるかもしれません)

public class Employee {

  public static void insertEmployee(.....) {
   // 処理 //
  }

  public static void selectEmployee(.....) {
   // 処理 //
  }

}

ストアド・プロシージャとして登録されるメソッドは public static void として定義される必要があります。

入力用の引数はそのまま引数として指定してしまってOKですが、出力および入出力に使用する引数は サイズが1の配列として定義する必要があります。

public class Employee {

  public static void insertEmployee1(String input1, int input2.....) {
   // 処理 //
  }

  public static void insertEmployee2(String[] output1, int[] output2.....) {
   // 処理 //
   output1[0] = "OK";
   output2[0] = 1;
  }

  public static void insertEmployee3(String[] inout1, int[] inout2.....) {
   String returnedString = inout1[0];
   int returnedInt = inout2[0];
   // 処理 //
   inout1[0] = "OK";
   inout2[0] = 1;
  }

}

SQLデータタイプとJavaのデータタイプとの互換性はこんなふうになっています。

パラメーターのデータ・タイプ

コネクションオブジェクトは以下のようにして定義します。呼び出される元の接続をそのまま使うようにします。

Connection con = DriverManager.getConnecion("jdbc:default:connection");

その他、マニュアルのJavaストアド・プロシージャーについての記述も参考にしてください。


以上のような約束をもとに、以前JDBCのサンプルプログラムで使用した insertの場合のプログラムをちょっと直すと、こんなかんじでストアド・プロシージャーになります。

import java.sql.*;
import java.io.*;

public class QEOLStoredProcs {
  public static void InsertSampleProc (String tkbang, String tknakj, String tkadr1, int[] insercount) 
    throws SQLException, Exception 
  {
    Connection con = DriverManager.getConnection("jdbc:default:connection");
    PreparedStatement stmt = null;
    String sql = "INSERT INTO QEOL.TOKMSP(TKBANG,TKNAKJ,TKADR1) VALUES(?,?,?)";
    stmt = con.prepareStatement(sql);
    stmt.setString(1, tkbang);
    stmt.setString(2, tknakj);
    stmt.setString(3, tkadr1);

    insercount[0] = stmt.executeUpdate(sql);

    try {
      if (stmt != null) stmt.close();
        if (con != null) con.close();
    }
    catch (SQLException e) { }
  }
}

次にselectの場合も同様です。

import java.sql.*;
import java.io.*;

public class QEOLStoredProcs {
  public static void SelectSampleProc (ResultSet[] rstokmsp) 
    throws SQLException, Exception 
  {
    Connection con = DriverManager.getConnection("jdbc:default:connection");
    Statement stmt = null;
    String sql = "SELECT TKBANG,TKNAKJ,TKADR1,TKADR2 FROM QEOL.TOKMSP";
    stmt = con.createStatement(sql);

    rstokmsp[0] = stmt.executeQuery(sql);

  }
}

こうした結果セットを返すストアド・プロシージャーの場合、結果セットと関連するステートメントはクローズしないようにしてください。
SQL文での例がマニュアルにありますので、そちらも参照してみてください。


上の例をまとめたのがこちらのプログラムです。

InsertするものとSelectするものをまとめてひとつのクラスにしています。

メソッド InsertSampleProc と SelectSampleProc がそれぞれ別のストアド・プロシージャーとして登録されます。

import java.sql.*;

public class QEOLStoredProcs {
  public static void SelectSampleProc (ResultSet[] rstokmsp)
    throws SQLException, Exception {
    Connection con = DriverManager.getConnection("jdbc:default:connection");
    Statement stmt = null;
    String sql = "SELECT TKBANG,TKNAKJ,TKADR1,TKADR2 FROM QEOL.TOKMSP";
    stmt = con.createStatement();
    rstokmsp[0] = stmt.executeQuery(sql);
  }

  public static void InsertSampleProc (String s1, String s2, String s3, int[] insertcount) 
    throws SQLException, Exception {
    Connection con = DriverManager.getConnection("jdbc:default:connection");
    PreparedStatement stmt = null;
    String sql = "INSERT INTO QEOL.TOKMSP(TKBANG,TKNAKJ,TKADR1) VALUES(?,?,?)";
    stmt = con.prepareStatement(sql);
    stmt.setString(1, s1);
    stmt.setString(2, s2);
    stmt.setString(3, s3);
    insertcount[0] = stmt.executeUpdate();
    try {
      if (stmt != null) stmt.close();
        if (con != null) con.close();
    }
    catch (SQLException e) { }
  }

}

コンパイルしたクラスは /QIBM/UserData/OS400/SQLLib/Function に置いてください。

こちらはオペレーション・ナビゲーターを使用して、エクスプローラーからドラッグ&ドロップでコピーした例です。

また、こちらのクラスはOS/400用に最適化しておいた方がパフォーマンスを考えればいいでしょう。

CRTJVAPGM CLSF(QEOLStoredProcs.class) OPTIMIZE(40)

ストアド・プロシージャの登録はオペレーション・ナビゲーターを使用して以下のように行います。

まず、データベースのアイコンを右クリックしてサブメニューを表示させ、「表示するライブラリーの選択」をクリックします。

こんな画面が出てきますので、ストアド・プロシージャを作成したい先のライブラリーを入力して「追加」ボタンを押してください。

結果としてこのように「ライブラリー」を選択すると、「表示するライブラリー」に選択されたもののみが表示されます。

該当のライブラリーのアイコンを選んで、右クリックして下記のように「新規作成」-「プロシージャー」-「外部」と選んで下さい。

以下のような画面が表示されます。

まず最初に「InsertSampleProc」の登録です。

「データ・アクセス」には「SQLデータの変更」を選択してください。(使うSQL文が"INSERT"ですから)

「パラメーター」タブに移ります。

以下のようにパラメーターを入力/出力/入出力それぞれ定義してください。

パラメーター名や長さを上書きで入力してください。「タイプ」や「In/Out」は以下の例のようにリストから選択できるようになっています。

結果として以下のようになります。

「パラメーター・スタイル」の「Java」も忘れずにチェックしてください。

「外部プログラム」タブで実際のプログラムを指定します。

クラス名 + ! + メソッド名で定義します。

同様に SelectSampleProc も定義します。

このストアド・プロシージャーは結果セットを返しますので、「結果セットの最大数」にその結果セットの数である「1」を指定します。

「データ・アクセス」には「SQLデータの読み取り」を指定します。

特に指定するパラメーターはありませんが、「パラメーター・スタイル」に「Java」を選択してください。

クラス名 + ! + メソッド名で実行されるストアド・プロシージャーの実体を定義します。

登録が無事に終わると、オペレーション・ナビゲーターの該当ライブラリーの中には以下のように定義されたストアド・プロシージャーが表示されるようになります。


このストアド・プロシージャーにアクセスするするクライアントはそれぞれこんなかんじになります。
こちらも以前のサンプルからちょっと変更して作成しました。

まず、最初に Select の方です。SelectSampleProc を呼び出すクライアントになります。

import java.sql.*;

public class CallingStoredProc1 {

public static void main(String[] args) {
  String url = "jdbc:as400://";
  String system = "asdomino";
  String user = "userr5";
  String password = "password";
  String tkbang,tknakj,tkadr1,tkadr2;
  Connection con = null;

  try {
    // JDBCドライバのロード
    Class.forName("com.ibm.as400.access.AS400JDBCDriver");

    // DB接続
    con = DriverManager.getConnection(url + system, user,password);

    // SQLコンテナ作成
    CallableStatement stmt = con.prepareCall("CALL QEOL.SelectSampleProc");

    // SQL実行
    ResultSet rs = stmt.executeQuery();

    // 検索結果取り出し
    while(rs.next()) {
      tkbang = rs.getString("TKBANG");
      tknakj = rs.getString("TKNAKJ");
      tkadr1 = rs.getString("TKADR1");
      tkadr2 = rs.getString("TKADR2");
      System.out.println("得意先コード : " + tkbang + ", 得意先名 : " + tknakj + ", 住所 : " + tkadr1 + tkadr2);
    }

  rs.close();
  stmt.close();

  }
  catch(SQLException e) {
    while(e != null) {
      System.err.println(e.getMessage());
      System.err.println(e.getSQLState());
      System.err.println(e.getErrorCode());
      System.out.println("");

      e = e.getNextException();
    }
  }
  catch(Exception e) {
    e.printStackTrace();
  }
  finally {
    try {
      con.close();
    }
  catch(SQLException e) {}
  }

}
}

次にこちらが InsertSampleProc を呼び出すクライアントです。

import java.sql.*;

public class CallingStoredProc2 {

public static void main(String[] args) {
  String url = "jdbc:as400://";
  String system = "asdomino";
  String user = "user";
  String password = "password";
  Connection con = null;

  try {
    // JDBCドライバのロード
    Class.forName("com.ibm.as400.access.AS400JDBCDriver");

    // DB接続
    con = DriverManager.getConnection(url + system, user,password);

    // SQLコンテナ作成
    String sql = "CALL QEOL.InsertSampleProc (?, ?, ?, ?)";
    CallableStatement stmt = con.prepareCall(sql);

    // SQL実行
    stmt.setString(1, "1");
    stmt.setString(2, "ABC");
    stmt.setString(3, "Rochester, MN");
    stmt.registerOutParameter(4, Types.INTEGER);
    stmt.executeUpdate();

    System.out.println("登録件数 : " + stmt.getInt(4));
    stmt.close();

  }
  catch(SQLException e) {
    while(e != null) {
      System.err.println(e.getMessage());
      System.err.println(e.getSQLState());
      System.err.println(e.getErrorCode());
      System.out.println("");

      e = e.getNextException();
    }
  }
  catch(Exception e) {
    e.printStackTrace();
  }
  finally {
    try {
      con.close();
    }
    catch(SQLException e) {}
  }

}
}

クライアントからの呼び出しかたですが、今回の例に載ってないものでは「値を返すストアド・プロシージャー」を呼び出す場合のやり方があります。
マニュアルに例が載っていますので、こちらも参考にしてください。

[Top Pageに戻る]

Ads by TOK2