Recuperación gradual de datos por medio de CLI

Hay dos formas en las que un usuario recupera datos procedentes de una tabla de DB2 Everyplace por medio de CLI:

En el caso de los datos binarios (BLOB) o datos de carácter (CHAR o VARCHAR), la columna puede ser muy larga. Es posible que el desarrollador de aplicaciones no desee asignar un almacenamiento intermedio que sea lo suficientemente grande como para que contenga toda la columna o que no pueda permitirse asignar un almacenamiento intermedio tan grande. Adicionalmente, en algunos casos la aplicación sólo requiere algunos fragmentos de la columna. En estos escenarios, se necesita la recuperación gradual de datos.

Procedimiento

Una característica de SQLGetData() permite a la aplicación utilizar llamadas repetidas para obtener, en secuencia, el valor de una única columna en fragmentos más manejables. Esencialmente, una llamada a SQLGetData() devuelve SQL_SUCCESS_WITH_INFO (con SQLSTATE 01004) para indicar que hay más datos para esta columna. SQLGetData() se llama repetidamente para obtener los restantes fragmentos de datos hasta que devuelva SQL_SUCCESS, lo que significa que se han recuperado todos los datos para esta columna.

Sintaxis


SQLRETURN SQLGetData (
SQLHSTMT StatementHandle, /* hstmt */
SQLUSMALLINT ColumnNumber, /* icol */
SQLSMALLINT TargetType, /* fCType */
SQLPOINTER TargetValuePtr, /* rgbValue */
SQLINTEGER BufferLength, /* cbValueMax */
SQLINTEGER *FAR StrLen_or_IndPtr); /* pcbValue */

Esta acción recuperará BufferLength bytes a la vez y StrLen_or_IndPtr indica el número de bytes restantes. El valor de retorno de la función es SQL_SUCCESS_WITH_INFO (con SQLSTATE 01004) si quedan bytes. En caso contrario, si el valor de retorno es SQL_SUCCESS, StrLen_or_IndPtr indica el número de bytes que DB2 Everyplace CLI tiene disponibles para volver al almacenamiento intermedio de TargetValuePtr. SQLGetData() puede utilizarse de este modo para recuperar columnas largas en el caso de que el tipo de datos C (TargetType) sea SQL_C_CHAR, SQL_C_BINARY o en el caso de que TargetType sea SQL_C_DEFAULT y el tipo de columna denote un binario o serie de caracteres.

Para utilizar esta característica de SQLGetData(), en primer lugar debe establecer un atributo de sentencia SQL_ATTR_GETDATA_MODE para SQL_PIECEMEAL_DATA. El valor por omisión de este atributo es SQL_CHUNK_DATA. La diferencia entre estas dos modalidades es que, en la modalidad SQL_CHUNK_DATA (que es la modalidad por omisión) y el momento en que se produce el truncamiento, el valor de retorno de SQLGetData() StrLen_or_IndPtr indica el número total de bytes de esta columna y la segunda llamada continúa recuperando datos del principio de la columna.

Ejemplo de fragmento de código

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 ) {
        // manejar BUFSIZ bytes de datos blob en almacenamiento intermedio
            : 
        sqlrc = SQLGetData (hstmt, 1, SQL_C_BINARY, (SQLPOINTER) buffer, BUFSIZ, &bufInd);
    } 
    if (sqlrc == SQL_SUCCESS) {  /* partial buffer on last GetData */
        // manejar bufInd bytes de datos blob en almacenamiento intermedio
            : 
    }