When Adaptive Server returns a LOB locator, use SQLGetData and SQLBindCol to retrieve the underlying prefetched LOB data by binding the column to SQL_C_CHAR or SQL_C_WCHAR for text locators, or to SQL_C_BINARY for image locators.
Set the SQL_ATTR_LOBLOCATOR attribute to enable or disable locators in a connection. If EnableLOBLocator has been specified in the connection string, SQL_ATTR_LOBLOCATOR is initialized with the value of EnableLOBLocator, otherwise, it is set to SQL_LOBLOCATOR_OFF, the default value. To enable locators, set the attribute to SQL_LOBLOCATOR_ON. Use SQLSetConnectAttr to set the attribute’s value and SQLGetConnectAttr to retrieve its value.
Use SQLSetStatementAttr to set SQL_ATTR_LOBLOCATOR_FETCHSIZE to specify the size—in bytes for binary data and in characters for character data—of the LOB data to retrieve. The default value, 0, indicates that prefetched data is not requested, while a value of -1 retrieves the entire LOB data.
If the underlying LOB data size of the column being
retrieved exceeds the prefetched data size that you have set, native
error 3202 is raised when an ODBC client attempts to directly retrieve
the data. When this happens, the client can retrieve the complete
data by calling SQLGetData to obtain the underlying
locator and perform all of the operations available on locators.
Example 1 Retrieves an image locator using SQLGetData when the prefetched data represents the complete LOB value:
//Set Autocommit off SQLRETURN sr; sr = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, 0); //Enable LOB Locator for this exchange sr = SQLSetConnectAttr(dbc, SQL_ATTR_LOBLOCATOR, (SQLPOINTER)SQL_LOCATOR_ON, 0); // Set size of prefetched LOB data sr = SQLSetStatementAttr(stmt, SQL_ATTR_LOBLOCATOR_FETCHSIZE, (SQLPOINTER)32768, 0); //Get a locator from the server SQLLEN lLOBLen = 0; Byte cBin[COL_SIZE]; SQLLEN lBin = sizeof(CBin); unsigned char cLOC[SQL_LOCATOR_SIZE]; SQLLEN lLOC = sizeof(cLOC); int id = 4; SQLLEN l1 = sizeof(int); SQLLEN idLen = sizeof(int); sr = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, idLen, 0, &id, idLen, &idLen); printError(sr, SQL_HANDLE_STMT, stmt); //Execute the select statement to return a locator sr = SQLExecDirect(stmt, selectCOL_SQL, SQL_NTS); printError(sr, SQL_HANDLE_STMT, stmt); sr = SQLFetch(stmt); printError(sr, SQL_HANDLE_STMT, stmt); //Retrieve the binary data (Complete Data is returned) sr = SQLGetData(stmt, 1, SQL_C_BINARY, cBin, lBin, &lBin); printError(sr, SQL_HANDLE_STMT, stmt); //Cleanup sr = SQLFreeStmt(stmt, SQL_UNBIND); sr = SQLFreeStmt(stmt, SQL_RESET_PARAMS); sr = SQLFreeStmt(stmt, SQL_CLOSE); SQLEndTran(SQL_HANDLE_DBC, dbc,SQL_COMMIT); //Disable LOB Locator for the future sr = SQLSetConnectAttr(dbc, SQL_ATTR_LOBLOCATOR, (SQLPOINTER)SQL_LOCATOR_OFF, 0);
Example 2 Retrieves an image locator using SQLGetData when prefetched data represents a truncated LOB value:
//Set Autocommit off SQLRETURN sr; sr = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, 0); //Enable LOB Locator for this exchange sr = SQLSetConnectAttr(dbc, SQL_ATTR_LOBLOCATOR, (SQLPOINTER)SQL_LOCATOR_ON, 0); //Set size of prefetched LOB data sr = SQLSetStatementAttr(stmt, SQL_ATTR_LOBLOCATOR_FETCHSIZE, (SQLPOINTER)32768, 0); //Get a locator from the server SQLLEN lLOBLen = 0; Byte cBin[COL_SIZE]; SQLLEN lBin = sizeof(CBin); unsigned char cLOC[SQL_LOCATOR_SIZE]; SQLLEN lLOC = sizeof(cLOC); int id = 4; SQLLEN l1 = sizeof(int); SQLLEN idLen = sizeof(int); sr = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, idLen, 0, &id, idLen, &idLen); printError(sr, SQL_HANDLE_STMT, stmt); //Execute the select statement to return a locator sr = SQLExecDirect(stmt, selectCOL_SQL, SQL_NTS); printError(sr, SQL_HANDLE_STMT, stmt); sr = SQLFetch(stmt); printError(sr, SQL_HANDLE_STMT, stmt); // Retrieve the binary data(Truncated data is returned) sr = SQLGetData(stmt, 1, SQL_C_BINARY, cBin, lBin, &lBin); if(sr == SQL_SUCCESS_WITH_INFO) { SQLTCHAR errormsg[ERR_MSG_LEN]; SQLTCHAR sqlstate[SQL_SQLSTATE_SIZE+1]; SQLINTEGER nativeerror = 0; SQLSMALLINT errormsglen = 0; retcode = SQLGetDiagRec(handleType, handle, 1, sqlstate, &nativeerror, errormsg, ERR_MSG_LEN, &errormsglen); printf("SqlState: %s Error Message: %s\n", sqlstate, errormsg); //Handle truncation of LOB data; if data was truncated call SQLGetData to // retrieve the locator. /* Warning returns truncated LOB data */ if (NativeError == 32028) //Error code may change { BYTE ImageLocator[SQL_LOCATOR_SIZE]; sr = SQLGetData(stmt, 1, SQL_C_IMAGE_LOCATOR, &ImageLocator, sizeof(ImageLocator), &Len); printError(sr, SQL_HANDLE_STMT, stmt); /* Perform locator specific calls using image Locator on a separate statement handle if needed */ } } //Cleanup sr = SQLFreeStmt(stmt, SQL_UNBIND); sr = SQLFreeStmt(stmt, SQL_RESET_PARAMS); sr = SQLFreeStmt(stmt, SQL_CLOSE); SQLEndTran(SQL_HANDLE_DBC, dbc,SQL_COMMIT); //Disable LOB Locator for the future sr = SQLSetConnectAttr(dbc, SQL_ATTR_LOBLOCATOR, (SQLPOINTER)SQL_LOCATOR_OFF, 0);