Hitachi

ノンストップデータベース HiRDB Version 10 SQLリファレンス


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手続きのコール元のコネクションのメタデータを使用して,情報を取得してください。