1.9.3 結果集合返却機能

結果集合返却機能を用いた場合,手続き中でカーソルを使用して検索した結果を,コール元で参照できます。

ここでは,手続きで結果集合を返却する方法,及びUAPで手続きが返却した結果集合を受け取る方法について説明します。

<この項の構成>
(1) SQL手続き定義の場合
(2) 外部Java手続き定義の場合
(3) 外部Java手続きの実体であるJavaメソッドの作成の場合
(4) 埋込み型UAPの作成の場合
(5) Javaを用いたUAPの作成の場合
(6) 留意事項

(1) SQL手続き定義の場合

CREATE PROCEDUREのDYNAMIC RESULT SETS句に,結果集合の最大数(コール元に返すカーソルの最大数)を指定します。また,手続きから結果集合として返却するカーソルのカーソル宣言では,WITH RETURNを指定します。

WITH RETURNを指定して宣言したカーソルを開いた状態のまま手続きを終了すると,カーソルの結果集合をコール元に返却できます。返却する結果集合が二つ以上ある場合は,カーソルを開いた順番で返却します。

SQL手続きの定義例を次に示します。

CREATE PROCEDURE ORDERED_EMPS(IN REGION INTEGER)
   DYNAMIC RESULT SETS 2
   BEGIN
       DECLARE CUR1 CURSOR WITH RETURN
           FOR SELECT id_no, name FROM emps_1
               WHERE id_no < REGION ORDER BY id_no;
       DECLARE CUR2 CURSOR WITH RETURN
           FOR SELECT id_no, name FROM emps_2
               WHERE id_no < REGION ORDER BY id_no;
       OPEN CUR1;
       OPEN CUR2;
   END;

(2) 外部Java手続き定義の場合

CREATE PROCEDUREのDYNAMIC RESULT SETS句に,結果集合の最大数(コール元に返すカーソルの最大数)を指定します。

外部Java手続きの定義例を次に示します。

CREATE PROCEDURE ORDERD_EMPS(IN REGION INTEGER)
   DYNAMIC RESULT SETS 2 LANGUAGE JAVA
   EXTERNAL NAME
     'jfile.jar:Routines3.orderedEmps
      (int,java.sql.ResultSet[],java.sql.ResultSet[])
      returns void'
   PARAMETER STYLE JAVA;

(3) 外部Java手続きの実体であるJavaメソッドの作成の場合

外部Java手続きの実体であるJavaメソッドの最後の引数に,java.sql.ResultSet[]型のパラメタを指定します。また,JavaメソッドはSQLを実行して結果集合を受け取り,java.sql.ResultSet[]型のパラメタである変数を設定します。

Javaメソッドの作成例を次に示します。

import java.sql.*;

public class Routines3 {
   public static void orderedEmps(int region,
       java.sql.ResultSet[] rs1, java.sql.ResultSet[] rs2)
   throws SQLException {
       java.sql.Connection conn=DriverManager.getConnection(
           "jdbc:hitachi:PrdbDrive","USER1","USER1");
       java.sql.PreparedStatement stmt1=
         conn.prepareStatement(
             "SELECT id_no,name FROM emps_1 WHERE id_no < ? ORDER BY id_no");
       stmt1.setInt(1, region);
       rs1[0]=stmt1.executeQuery();
       java.sql.PreparedStatement stmt2=
         conn.prepareStatement(
             "SELECT id_no,name FROM emps_2 WHERE id_no < ? ORDER BY id_no");
       stmt2.setInt(1, region);
       rs2[0]=stmt2.executeQuery();
       return;
   }
}

(4) 埋込み型UAPの作成の場合

埋込み型UAPから手続きを実行し,ALLOCATE CURSOR文によって手続きから返却された結果集合の組がカーソルに割り当てられます。カーソルはその先頭の結果集合と関連づけられ,FETCH文によって結果集合からデータを取り出すことができます。

二つ目以降の結果集合は結果集合の組に割り当てられます。前の結果集合と関連づけられているカーソルに対してCLOSE文を実行すると,カーソルと関連づけられ,FETCH文によって結果集合からデータを取り出すことができます。

C言語による埋込み型UAPの作成例を次に示します。

EXEC SQL WHENEVER SQLERROR GOTO error_end;
EXEC SQL CALL ORDERED_EMP(1000);
if (SQLCODE==120) {                   /* 結果集合の組が返却された */
   EXEC SQL ALLOCATE GLOBAL :cur1 FOR PROCEDURE ORDERED_EMP;
                                     /* カーソルを割り当てる */
                                     /* cur1にはカーソル名を指定する */
   while (1) {
       while (1) {
           EXEC SQL WHENEVER NOT FOUND DO break;
           EXEC SQL FETCH GLOBAL :cur1 INTO :emp_id, :emp_name;
           printf("ID No.=%s¥n", emp_id);
           printf("Name=%s¥n", emp_name);
       }
       EXEC SQL WHENEVER NOT FOUND DO break;
       EXEC SQL CLOSE GLOBAL :cur1;
   }
}
error_end:

(5) Javaを用いたUAPの作成の場合

Java言語で記述したUAPから手続きを実行し,手続きから送られてくる結果集合を受け取ります。

java.sql.PreparedStatement.execute()を使用して結果集合を受け取る場合の,Javaを用いたUAPの作成例を次に示します。

java.sql.CallableStatement stmt=conn.preparecall(
   "call ordered_emps(?)}");
stmt.setInt(1,3);
stmt.execute();                             //結果集合を
java.sql.ResoltSet rs=smmt.getResultSet();  //受け取る
while(rs.next()) {
   int id_no=rs.getInt(1);
   java.lang.String name=rs.getString(2);
   System.out.println("ID No.="+id_no);
   System.out.println("Name="+name);
   System.out.println();
}
rs.close();
while (stmt.getMoreResults()){
   rs = stmt.getResultSet();
   while(rs.next()) {
       int id_no=rs.getInt(1);
       java.lang.String name=rs.getString(2);
       System.out.println("ID No.="+id_no);
       System.out.println("Name="+name);
       System.out.println();
   }
   rs.close();
}

(6) 留意事項

外部Java手続き中で取得したDatabaseMetaDataクラスの,メソッドが返却する結果集合(ResultSet)は,動的結果集合として返却できません。外部Java手続きのコール元のコネクションのメタデータを使用して,情報を取得してください。