1.9.3 結果集合返却機能
結果集合返却機能を用いた場合,手続き中でカーソルを使用して検索した結果を,コール元で参照できます。
ここでは,手続きで結果集合を返却する方法,及びUAPで手続きが返却した結果集合を受け取る方法について説明します。
- 〈この項の構成〉
(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.ResultSet 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(); 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手続きのコール元のコネクションのメタデータを使用して,情報を取得してください。