10. Understanding ODBC Connectivity : ODBC Programming : Fetched Data : Column-wise versus Row-wise Binding
 
Share this page                  
Column-wise versus Row-wise Binding
The previous SQLRecordScroll() example depicts column-wise binding, which is the default. In column-wise binding, the variable arrays describe the columns of data to be fetched.
It is also possible to set up structures in your program that describe the rows to be fetched, rather than the columns. This is called row-wise binding.
The following program excerpt fetches exactly the same data as the SQLRecordScroll() example, but uses row-wise binding instead of column-wise binding. The structure typedef MODEL_ROW can be considered a snapshot of information about each row. Each column in the row structure consists of the data to be fetched and a row status indicator.
#define ROWS 5
#define MODEL_LEN 21
 
/*
** Describe a row in the result set.
*/
typedef struct
{
    SQLCHAR       model[MODEL_LEN];  /* The data to be fetched */
    SQLINTEGER    orind;             /* Len or status indicator */
} MODEL_ROW;
 
MODEL_ROW      model_row[ROWS];   /* The record set */
SQLUSMALLINT   rowStatus[ROWS];   /* Status of each row */
SQLHSTMT       hstmt;             /* Statement handle */
RETCODE        rc=SQL_SUCCESS;    /* Return status */
int            i;                 /* Loop counter */
SQLUINTEGER    numRowsFetched;    /* Number of rows fetched */
 
/*
** Declare that the record set is organized according to rows.
*/
SQLSetStmtAttr( hstmt, SQL_ATTR_ROW_BIND_TYPE,
    (SQLPOINTER)sizeof( MODEL_ROW ), 0 );
/*
** Declare the number of rows in the result set.
*/
SQLSetStmtAttr( hstmt, SQL_ATTR_ROW_ARRAY_SIZE,
    (SQLPOINTER)ROWS, 0 );
/*
** Bind to a status array reporting on each row fetched.
*/
SQLSetStmtAttr( hstmt, SQL_ATTR_ROW_STATUS_PTR,
    (SQLPOINTER)rowStatus, 0 );
/*
** Bind to an integer reporting on the number of rows fetched.
*/
SQLSetStmtAttr( hstmt, SQL_ATTR_ROWS_FETCHED_PTR,
    (SQLPOINTER)&numRowsFetched, 0 );
/*
** Execute the select statement.
*/
SQLExecDirect( hstmt, "SELECT model from cars", SQL_NTS );
    
/*
** Bind each column in the record set structure.
*/
SQLBindCol( hstmt,                  /* Statement handle */
    1,                              /* Column number */
    SQL_C_CHAR,                     /* Bind to C string */
    &model_row[0].model,            /* Column to fetch */
    sizeof( model_row[0].model ),   /* Length of data */
    &model_row[0].orind );          /* Len or status indicator */
/*
** Fetch the data in a loop.
*/
while ( TRUE )
{
    rc = SQLFetchScroll( hstmt, SQL_FETCH_NEXT, 0 ) )
    /*
    ** Break out of the loop at end-of-data.
    */
    if ( rc == SQL_NO_DATA_FOUND )
        break;
    
    /*
    ** Break out of the loop if an error is found.
    */
    if ( !SQL_SUCCEEDED( rc ) )
    {
        printf( "Error on SQLFetchScroll(), status is %d\n", rc );
        break;
    }
    /*
    ** Display the result set.
    */
    for (i = 0; i < numRowsFetched; i++)
    {
        printf("Model: %s\n", model_row[i].model);
    }
} /* end while */