There are two ways for a user to retrieve data from a DB2 Everyplace table through CLI:
In the case of binary data (BLOB) or character data (CHAR or VARCHAR), the column can be very long. The application developer may not want to allocate a buffer big enough to hold the whole column, or may not be able to afford to allocate a buffer this large. Additionally, in some cases the application only requires some pieces of the column. In these scenarios, piecemeal retrieval of data is needed.
Procedure
A feature of SQLGetData() allows the application to use repeated calls to obtain, in sequence, the value of a single column in more manageable pieces. Essentially, a call to SQLGetData() returns SQL_SUCCESS_WITH_INFO (with SQLSTATE 01004) to indicate more data exists for this column. SQLGetData() is called repeatedly to get the remaining pieces of data until it returns SQL_SUCCESS, signifying that the entire data has been retrieved for this column.
Syntax
SQLRETURN SQLGetData (
SQLHSTMT StatementHandle, /* hstmt */
SQLUSMALLINT ColumnNumber, /* icol */
SQLSMALLINT TargetType, /* fCType */
SQLPOINTER TargetValuePtr, /* rgbValue */
SQLINTEGER BufferLength, /* cbValueMax */
SQLINTEGER *FAR StrLen_or_IndPtr); /* pcbValue */
This will retrieve BufferLength bytes at a time, and StrLen_or_IndPtr indicates the number of bytes remaining. The return value of the function is SQL_SUCCESS_WITH_INFO (with SQLSTATE 01004) if there are bytes remaining. Otherwise, if the return value is SQL_SUCCESS, StrLen_or_IndPtr indicates the number of bytes that DB2 Everyplace CLI has available to return in the TargetValuePtr buffer. SQLGetData() can be used this way to retrieve long columns if the C data type (TargetType) is SQL_C_CHAR, SQL_C_BINARY, or if TargetType is SQL_C_DEFAULT and the column type denotes a binary or character string.
To use this feature of SQLGetData(), you must first set a statement attribute SQL_ATTR_GETDATA_MODE to SQL_PIECEMEAL_DATA. The default value of this attribute is SQL_CHUNK_DATA. The difference between these two modes is that, in SQL_CHUNK_DATA mode (which is the default mode), and when truncation occurs, SQLGetData()'s return value StrLen_or_IndPtr indicates the total number of bytes of this column, and the second call still retrieves data from the very beginning of the column.
Example code fragment
sqlrc = SQLSetStmtAttr(hstmt, SQL_ATTR_GETDATA_MODE, (SQLPOINTER) SQL_PIECEMEAL_DATA, 0); SQLCHAR * stmt = (SQLCHAR *) "SELECT blobColumn FROM t1 where c1 = ?"; sqlrc = SQLPrepare( hstmt, stmt, SQL_NTS ) ; sqlrc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, ...); sqlrc = SQLExecute( hstmt ) ; sqlrc = SQLFetch( hstmt ); /* get BUFSIZ bytes at a time, bufInd indicates number of Bytes LEFT */ sqlrc = SQLGetData (hstmt, 1, SQL_C_BINARY, (SQLPOINTER) buffer, BUFSIZ, &bufInd); while( sqlrc == SQL_SUCCESS_WITH_INFO ) { // handle BUFSIZ bytes of blob data in buffer : sqlrc = SQLGetData (hstmt, 1, SQL_C_BINARY, (SQLPOINTER) buffer, BUFSIZ, &bufInd); } if (sqlrc == SQL_SUCCESS) { /* partial buffer on last GetData */ // handle bufInd bytes of blob data in buffer : }