SQLMoreResults
SQLMoreResults permite que la aplicación recupere varios conjuntos de filas de resultados. Una instrucción SELECT Transact-SQL con una cláusula COMPUTE o un lote enviadoo de ODBC o instrucciones Transact-SQL, provocan que el controlador ODBC de SQL Server Native Cliente generen varios conjuntos de resultados. SQL Server no permite la creación de un cursor de servidor para procesar los resultados en ninguno de los casos. Por consiguiente, el programador debe asegurarse de que la instrucción ODBC bloquea la tabla. El programador debe agotar los datos devueltos o cancelar la instrucción ODBC antes de procesar los datos de otras instrucciones activas en la conexión.
[!NOTA]
Una instrucción SELECT de Transact-SQL que contiene una cláusula COMPUTE solo se admite cuando se establece la conexión a una versión de servidor anterior a SQL Server 2012.
El programador puede determinar las propiedades de las columnas y filas de conjuntos de resultados generadas por la cláusula COMPUTE de una instrucción SELECT Transact-SQL. Para obtener información más detallada, vea SQLColAttribute.
Cuando se llama a SQLMoreResults con filas de datos no capturadas en el conjunto de resultados, se pierden esas filas y pasan a estar disponibles los datos de fila del conjunto de filas de resultados siguiente.
Ejemplos
void GetComputedRows
(
SQLHSTMT hStmt
)
{
SQLUSMALLINT nCols;
SQLUSMALLINT nCol;
PODBCSETINFO pODBCSetInfo = NULL;
SQLRETURN sRet;
UINT nRow;
SQLINTEGER nComputes = 0;
SQLINTEGER nSet;
BYTE* pValue;
// If SQLNumResultCols failed, then some error occurred in
// statement execution. Exit.
if (!SQL_SUCCEEDED(SQLNumResultCols(hStmt, (SQLSMALLINT*) &nCols)))
{
goto EXIT;
}
// Determine the presence of COMPUTE clause result sets. The SQL
// Server Native Client ODBC driver uses column attributes to report multiple
// sets. The column number must be less than or equal to the
// number of columns returned. You are guaranteed to have at least
// one, so use '1' for the SQLColAttribute ColumnNumber
// parameter.
SQLColAttribute(hStmt, 1, SQL_CA_SS_NUM_COMPUTES,
NULL, 0, NULL, (SQLPOINTER) &nComputes);
// Create a result info structure pointer array, one element for
// the normal result rows and one for each compute result set.
// Initialize the array to NULL pointers.
pODBCSetInfo = new ODBCSETINFO[1 + nComputes];
// Process the result sets...
nSet = 0;
while (TRUE)
{
// If required, get the column information for the result set.
if (pODBCSetInfo[nSet].pODBCColInfo == NULL)
{
if (pODBCSetInfo[nSet].nCols == 0)
{
SQLNumResultCols(hStmt, (SQLSMALLINT*) &nCols);
pODBCSetInfo[nSet].nCols = nCols;
}
if (GetColumnsInfo(hStmt, pODBCSetInfo[nSet].nCols,
&(pODBCSetInfo[nSet].pODBCColInfo)) == SQL_ERROR)
{
goto EXIT;
}
}
// Get memory for bound return values if required.
if (pODBCSetInfo[nSet].pRowValues == NULL)
{
CreateBindBuffer(&(pODBCSetInfo[nSet]));
}
// Rebind columns each time the result set changes.
myBindCols(hStmt, pODBCSetInfo[nSet].nCols,
pODBCSetInfo[nSet].pODBCColInfo,
pODBCSetInfo[nSet].pRowValues);
// Set for ODBC row array retrieval. Fast retrieve for all
// sets. COMPUTE row sets have only a single row, but
// normal rows can be retrieved in blocks for speed.
SQLSetStmtAttr(hStmt, SQL_ATTR_ROW_BIND_TYPE,
(void*) pODBCSetInfo[nSet].nResultWidth, SQL_IS_UINTEGER);
SQLSetStmtAttr(hStmt, SQL_ATTR_ROW_ARRAY_SIZE,
(void*) pODBCSetInfo[nSet].nRows, SQL_IS_UINTEGER);
SQLSetStmtAttr(hStmt, SQL_ATTR_ROWS_FETCHED_PTR,
(void*) &nRowsFetched, sizeof(SQLINTEGER));
while (TRUE)
{
// In ODBC 3.x, SQLFetch supports arrays of bound rows or
// columns. SQLFetchScroll (or ODBC 2.x SQLExtendedFetch)
// is not necessary to support fastest retrieval of
// data rows.
if (!SQL_SUCCEEDED(sRet = SQLFetch(hStmt)))
{
break;
}
for (nRow = 0; nRow < (UINT) nRowsFetched; nRow++)
{
for (nCol = 0; nCol < pODBCSetInfo[nSet].nCols;
nCol++)
{
// Processing row and column values...
}
}
}
// sRet is not SQL_SUCCESS and is not SQL_SUCCESS_WITH_INFO.
// If it's SQL_NO_DATA, then continue. If it's an
// error state, stop.
if (sRet != SQL_NO_DATA)
{
break;
}
// If there's another set waiting, determine the result set
// indicator. The indicator is 0 for regular row sets or an
// ordinal indicating the COMPUTE clause responsible for the
// set.
if (SQLMoreResults(hStmt) == SQL_SUCCESS)
{
sRet = SQLColAttribute(hStmt, 1, SQL_CA_SS_COMPUTE_ID,
NULL, 0, NULL, (SQLPOINTER) &nSet);
}
else
{
break;
}
}
EXIT:
// Clean-up anything dynamically allocated and return.
return;
}
Vea también
Conceptos
Detalles de implementación de la API de ODBC