結果集合返却機能を用いた場合,手続き中でカーソルを使用して検索した結果を,コール元で参照できます。
ここでは,手続きで結果集合を返却する方法,及びUAPで手続きが返却した結果集合を受け取る方法について説明します。
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;
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;
外部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;
}
}
埋込み型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:
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();
}
外部Java手続き中で取得したDatabaseMetaDataクラスの,メソッドが返却する結果集合(ResultSet)は,動的結果集合として返却できません。外部Java手続きのコール元のコネクションのメタデータを使用して,情報を取得してください。