SQLMoreResults
적용 대상: SQL Server Azure SQL Database Azure SQL Managed Instance Azure Synapse Analytics Analytics Platform System(PDW)
SQLMoreResults 를 사용하면 애플리케이션이 여러 개의 결과 행 집합을 검색할 수 있습니다. COMPUTE 절을 포함하는 Transact-SQL SELECT 문 또는 제출된 ODBC 또는 Transact-SQL 문 일괄 처리로 인해 SQL Server Native Client ODBC 드라이버가 여러 결과 집합을 생성합니다. SQL Server는 두 경우 모두 결과를 처리하는 서버 커서를 만드는 것을 허용하지 않습니다. 따라서 개발자는 ODBC 문으로 인해 차단되지 않도록 해야 합니다. 개발자는 반환된 데이터를 소진하거나 연결에 대한 다른 활성 문의 데이터를 처리하기 전에 ODBC 문을 취소해야 합니다.
참고 항목
COMPUTE 절을 포함하는 Transact-SQL SELECT 문은 SQL Server 2012(11.x) 이전의 서버 버전에 연결할 때만 지원됩니다.
개발자는 Transact-SQL SELECT 문의 COMPUTE 절에 의해 생성되는 결과 집합 열 및 행의 속성을 확인할 수 있습니다. 자세한 내용은 SQLColAttribute를 참조 하세요.
SQLMoreResults가 결과 집합에 없는 데이터 행을 사용하여 호출되면 해당 행이 손실되고 다음 결과 행 집합의 행 데이터를 사용할 수 있게 됩니다.
예제
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;
}