SQLMoreResults() - Check for more result sets
SQLMoreResults() returns more information
about a statement handle. The information can be associated with an
array of input parameter values for a query, or a stored procedure
that returns results sets.
ODBC specifications for SQLMoreResults()
| ODBC specification level | In X/Open CLI CAE specification? | In ISO CLI specification? |
|---|---|---|
| 1.0 | No | No |
Syntax
SQLRETURN SQLMoreResults (SQLHSTMT hstmt);Function arguments
The following table lists the data type, use, and description for each argument in this function.
| Data type | Argument | Use | Description |
|---|---|---|---|
| SQLHSTMT | hstmt | input | Specifies the statement handle on which results are returned. |
Usage
- A
parameterized query with an array of input parameter values that
SQLSetStmtAttr()andSQLBindParameter()specify - A stored procedure that contains SQL queries that leaves open cursors on the result sets that it generates (result sets are accessible when a stored procedure has finished execution if cursors on these result sets remain open)
After you completely process a result set, call SQLMoreResults() to
determine if another result set is available. When you call SQLMoreResults(),
this function discards rows that were not fetched in the current result
set by closing the cursor. If another result set is available SQLMoreResults() returns
SQL_SUCCESS.
If all the result sets have been processed, SQLMoreResults() returns
SQL_NO_DATA_FOUND.
If you call SQLFreeStmt() with
the fOption argument set to SQL_CLOSE or
you call SQLFreeHandle() is called with the HandleType argument
set to SQL_HANDLE_STMT, these functions discard all pending result
sets for the statement handle on which they are called.
Return codes
SQLMoreResults(),
it returns one of the following values: - SQL_SUCCESS
- SQL_SUCCESS_WITH_INFO
- SQL_ERROR
- SQL_INVALID_HANDLE
- SQL_NO_DATA_FOUND
Diagnostics
The following table lists each SQLSTATE that this function generates, with a description and explanation for each value.
| SQLSTATE | Description | Explanation |
|---|---|---|
| 08S01 | Communication link failure. | The communication link between the application and data source fails before the function completes. |
| 58004 | Unexpected system failure. | Unrecoverable system error. |
| HY001 | Memory allocation failure. | Db2 ODBC is not able to allocate the required memory to support the execution or the completion of the function. |
| HY010 | Function sequence error. | The function is called during a data-at-execute
operation. (That is, the function is called during a procedure that
uses the SQLParamData() or SQLPutData() functions.) |
| HY013 | Unexpected memory handling error. | Db2 ODBC is not able to access the memory that is required to support execution or completion of the function. |
Additionally, SQLMoreResults() can return
all SQLSTATEs that are associated with SQLExecDirect() except
for HY009, HY014, and HY090.
Restrictions
The ODBC specification of SQLMoreResults() allows
row-counts that are associated with the execution of parameterized
INSERT, UPDATE, and DELETE statements with arrays of input parameter
values to be returned. However, Db2 ODBC
does not support the return of this count information.
Example
SQLMoreResults() to check
for additional result sets. /* ... */
#define NUM_CUSTOMERS 25
SQLCHAR stmt[] =
{ "WITH " /* Common Table expression (or Define Inline View) */
"order (ord_num, cust_num, prod_num, quantity, amount) AS "
"( "
"SELECT c.ord_num, c.cust_num, l.prod_num, l.quantity, "
"price(char(p.price, '.'), p.units, char(l.quantity, '.')) "
"FROM ord_cust c, ord_line l, product p "
"WHERE c.ord_num = l.ord_num AND l.prod_num = p.prod_num "
"AND cust_num = CNUM(cast (? as integer)) "
"), "
"totals (ord_num, total) AS "
"( "
"SELECT ord_num, sum(decimal(amount, 10, 2)) "
"FROM order GROUP BY ord_num "
") "
/* The 'actual' SELECT from the inline view */
"SELECT order.ord_num, cust_num, prod_num, quantity, "
"DECIMAL(amount,10,2) amount, total "
"FROM order, totals "
"WHERE order.ord_num = totals.ord_num "
};
/* Array of customers to get list of all orders for */
SQLINTEGER Cust[]=
{
10, 20, 30, 40, 50, 60, 70, 80, 90, 100,
110, 120, 130, 140, 150, 160, 170, 180, 190, 200,
210, 220, 230, 240, 250
};
#define NUM_CUSTOMERS sizeof(Cust)/sizeof(SQLINTEGER)
/* Row-wise (Includes buffer for both column data and length) */
struct {
SQLINTEGER Ord_Num_L;
SQLINTEGER Ord_Num;
SQLINTEGER Cust_Num_L;
SQLINTEGER Cust_Num;
SQLINTEGER Prod_Num_L;
SQLINTEGER Prod_Num;
SQLINTEGER Quant_L;
SQLDOUBLE Quant;
SQLINTEGER Amount_L;
SQLDOUBLE Amount;
SQLINTEGER Total_L;
SQLDOUBLE Total;
} Ord[ROWSET_SIZE];
SQLUINTEGER pirow = 0;
SQLUINTEGER pcrow;
SQLINTEGER i;
SQLINTEGER j;
/* ... */
/* Get details and total for each order row-wise */
rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
rc = SQLParamOptions(hstmt, NUM_CUSTOMERS, &pirow);
rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER,
0, 0, Cust, 0, NULL);
rc = SQLExecDirect(hstmt, stmt, SQL_NTS);
/* SQL_ROWSET_SIZE sets the max number of result rows to fetch each time */
rc = SQLSetStmtAttr(hstmt, SQL_ATTR_ROWSET_SIZE, ROWSET_SIZE, 0);
/* Set size of one row, used for row-wise binding only */
rc = SQLSetStmtAttr(hstmt, SQL_ATTR_BIND_TYPE, (void*)sizeof(Ord)/ROW_SIZE, 0);
/* Bind column 1 to the Ord_num Field of the first row in the array*/
rc = SQLBindCol(hstmt, 1, SQL_C_LONG, (SQLPOINTER) &Ord[0].Ord_Num, 0,
&Ord[0].Ord_Num_L);
/* Bind remaining columns ... */
/* ... */
/* NOTE: This sample assumes that an order never has more
rows than ROWSET_SIZE. A check should be added below to call
SQLExtendedFetch multiple times for each result set.
*/
do /* for each result set .... */
{ rc = SQLExtendedFetch(hstmt, SQL_FETCH_NEXT, 0, &pcrow, NULL);
if (pcrow > 0) /* if 1 or more rows in the result set */
{
i = j = 0;
printf("**************************************\n");
printf("Orders for Customer: %ld\n", Ord[0].Cust_Num);
printf("**************************************\n");
while (i < pcrow)
{ printf("\nOrder #: %ld\n", Ord[i].Ord_Num);
printf(" Product Quantity Price\n");
printf(" -------- ---------------- ------------\n");
j = i;
while (Ord[j].Ord_Num == Ord[i].Ord_Num)
{ printf(" %8ld %16.7lf %12.2lf\n",
Ord[i].Prod_Num, Ord[i].Quant, Ord[i].Amount);
i++;
}
printf(" ============\n");
printf(" %12.2lf\n", Ord[j].Total);
} /* end while */
} /* end if */
}
while ( SQLMoreResults(hstmt) == SQL_SUCCESS);
/* ... */