SQLGetData
SQLGetData is used to retrieve result set data without binding column values. SQLGetData can be called successively on the same column to retrieve large amounts of data from a column with a text, ntext, or image data type.
There is no requirement that an application bind variables to fetch result set data. The data of any column can be retrieved from the SQL Native Client ODBC driver by using SQLGetData.
The SQL Native Client ODBC driver does not support using SQLGetData to retrieve data in random column order. All unbound columns processed with SQLGetData must have higher column ordinals than the bound columns in the result set. The application must process data from the lowest unbound ordinal column value to the highest. Attempting to retrieve data from a lower ordinally numbered column results in an error. If the application is using server cursors to report result set rows, the application can refetch the current row and then fetch the value of a column. If a statement is executed on the default read-only, forward-only cursor, you must re-execute the statement to back up SQLGetData.
The SQL Native Client ODBC driver accurately reports the length of text, ntext, and image data retrieved using SQLGetData. The application can make good use of the StrLen_or_IndPtr parameter return to retrieve long data rapidly.
Note
For large value types, StrLen_or_IndPtr will return SQL_NO_TOTAL in cases of data truncation.
Examples
SQLHDBC hDbc = NULL;
SQLHSTMT hStmt = NULL;
long lEmpID;
PBYTE pPicture;
SQLINTEGER pIndicators[2];
// Get an environment, connection, and so on.
...
// Get a statement handle and execute a command.
SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt);
if (SQLExecDirect(hStmt,
(SQLCHAR*) "SELECT EmployeeID, Photo FROM Employees",
SQL_NTS) == SQL_ERROR)
{
// Handle error and return.
}
// Retrieve data from row set.
SQLBindCol(hStmt, 1, SQL_C_LONG, (SQLPOINTER) &lEmpID, sizeof(long),
&pIndicators[0]);
while (SQLFetch(hStmt) == SQL_SUCCESS)
{
printf("EmployeeID: %d\n", lEmpID);
// Call SQLGetData to determine the amount of data that's waiting.
if (SQLGetData(hStmt, 2, SQL_C_BINARY, pPicture, 0, &pIndicators[1])
== SQL_SUCCESS_WITH_INFO)
{
printf("Photo size: %ld\n\n", pIndicators[1]);
// Get all the data at once.
pPicture = new BYTE[pIndicators[1]];
if (SQLGetData(hStmt, 2, SQL_C_DEFAULT, pPicture,
pIndicators[1], &pIndicators[1]) != SQL_SUCCESS)
{
// Handle error and continue.
}
delete [] pPicture;
}
else
{
// Handle error on attempt to get data length.
}
}
See Also
Concepts
ODBC API Implementation Details