JDBC Tutorials - Herong's Tutorial Notes
Dr. Herong Yang, Version 2.11

Retrieving Multiple ResultSet Objects

This section describes how to retrieve multiple ResultSet objects from a stored procedure call.

If a stored procedure is returning multiple result sets, you should execute its CallableStatement object with the execute() method. In the case, an internal pointer will be maintained inside the CallableStatement object. This pointer is pointing the current result, which could be a result set or a update count.

If the current result is a result set, you can use the getResultSet() method to retrieve it into a ResultSet object.

If the current result is an update count, you can use the getUpdateCount() method to retrieve it as an integer.

To move the internal pointer to the next result, you can use the getMoreResult() method.

In a previous tutorial, I defined a store procedure called, HeadTail(), which returns 2 result sets. The program below shows you to create a CallableStatement object to execute this stored procedure:

/**
 * MySqlCallMultipleResultSet.java
 * Copyright (c) 2007 by Dr. Herong Yang. All rights reserved.
 */
import java.sql.*;
public class MySqlCallMultipleResultSet {
  public static void main(String [] args) {
    Connection con = null;
    try {
      com.mysql.jdbc.jdbc2.optional.MysqlDataSource ds 
        = new com.mysql.jdbc.jdbc2.optional.MysqlDataSource();
      ds.setServerName("localhost");
      ds.setPortNumber(3306);
      ds.setDatabaseName("HerongDB");
      ds.setUser("Herong");
      ds.setPassword("TopSecret");
      con = ds.getConnection();

// Create CallableStatement
      CallableStatement cs = con.prepareCall("CALL HeadTail(?)");

// Register OUT parameters
      cs.registerOutParameter(1, java.sql.Types.INTEGER);     

// Execute the CALL statement and expecting multiple result sets
      boolean isResultSet = cs.execute();

// First ReulstSet object
      if (!isResultSet) {
        System.out.println("The first result is not a ResultSet.");
        return;
      }

// First ReulstSet object
      System.out.println("Head of the table:");
      ResultSet res = cs.getResultSet();
      while (res.next()) {
        System.out.println("  "+res.getInt("ID")
          +", "+res.getString("FirstName")
          +", "+res.getString("LastName")
          +", "+res.getTimestamp("ModTime"));
        
      }
      res.close();

// Move to the next result
      isResultSet = cs.getMoreResults();
      if (!isResultSet) {
        System.out.println("The next result is not a ResultSet.");
        return;
      }

// Second ReulstSet object
      System.out.println("Tail of the table:");
      res = cs.getResultSet();
      while (res.next()) {
        System.out.println("  "+res.getInt("ID")
          +", "+res.getString("FirstName")
          +", "+res.getString("LastName")
          +", "+res.getTimestamp("ModTime"));
        
      }
      res.close();
      
// Retrieve OUT parameters
      System.out.println("Total number of records: "+cs.getInt(1));

// Close resource
      cs.close();

      con.close();
    } catch (Exception e) {
      System.err.println("Exception: "+e.getMessage());
      e.printStackTrace();
    }
  }
}

The output of the program perfectly matches my expectation:

C:\>javac -cp .;\local\lib\mysql-connector-java-5.0.7-bin.jar
  MySqlCallMultipleResultSet.java

C:\>java -cp .;\local\lib\mysql-connector-java-5.0.7-bin.jar
  MySqlCallMultipleResultSet

Head of the table:
  80029, 2265, 9e559, 2006-12-31 23:59:59.0
  80030, 378, 48189, 2007-08-31 21:35:14.0
  80031, 1a46, 108f3, 2007-08-31 21:35:14.0
  80032, 44f, c8511, 2007-08-31 21:35:14.0
  80033, 1e9a, 51ca6, 2007-08-31 21:35:14.0
  80034, 665, 6eb12, 2007-08-31 21:35:14.0
  80035, 1b97, 30e6d, 2007-08-31 21:35:14.0
  80036, 3d8, 270d6, 2007-08-31 21:35:14.0
  80037, 26a3, b2290, 2007-08-31 21:35:14.0
  80038, 1d65, d9d6d, 2007-08-31 21:35:14.0

Tail of the table:
  90029, Herong, Yang, 2006-12-31 23:59:59.0
  90028, 545, 728d4, 2007-08-31 21:35:17.0
  90027, 169b, 1f61d, 2007-08-31 21:35:17.0
  90026, 2559, 737b4, 2007-08-31 21:35:17.0
  90025, 1db2, 48b31, 2007-08-31 21:35:17.0
  90024, 149, cdf71, 2007-08-31 21:35:17.0
  90023, 12a5, 8a909, 2007-08-31 21:35:17.0
  90022, 1b67, c6f96, 2007-08-31 21:35:17.0
  90021, 12a9, 20ac8, 2007-08-31 21:35:17.0
  90020, 18a4, 1ffb4, 2007-08-31 21:35:17.0

Total number of records: 10001

Sections in This Chapter

Overview of CallableStatement Objects

"CREATE PROCEDURE" - Creating a Simple Procedure

Creating Procedures with IN and OUT Parameters

Creating Procedures with INOUT Parameters

Creating Procedures with Multiple Queries

Creating CallableStatement Objects with prepareCall()

Capturing ResultSet with executeQuery()

Creating CallableStatement Objects with Parameters

Common Errors with CallableStatement Parameters

Creating CallableStatement Objects with INOUT Parameters

Retrieving Multiple ResultSet Objects

Executing Stored Procedures without Permission

getProcedures() - Listing Stored Procedures

Dr. Herong Yang, updated in 2007
Retrieving Multiple ResultSet Objects