/******************************************************************************* ** ** Source File Name = tbread.c 1.7 ** ** Licensed Materials - Property of IBM ** ** (C) COPYRIGHT International Business Machines Corp. 1995, 2000 ** All Rights Reserved. ** ** US Government Users Restricted Rights - Use, duplication or ** disclosure restricted by GSA ADP Schedule Contract with IBM Corp. ** ** ** PURPOSE : ** Shows how to read tables. ** ** For more information on programming in CLI see the: ** - "Building CLI Applications" section of the Application Building Guide, and the ** - CLI Guide and Reference. ** ** For more information on the SQL language see the SQL Reference. ** *******************************************************************************/ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sqlcli1.h> #include "utilcli.h" /* Header file for CLI sample code */ /* methods to perform select */ int TbBasicSelectUsingFetchAndBindCol( SQLHANDLE) ; int TbBasicSelectUsingFetchAndGetData( SQLHANDLE) ; int SysTbSelect( SQLHANDLE) ; int TbSelectWithParam( SQLHANDLE) ; int TbSelectWithUnknownOutCols( SQLHANDLE) ; #define ROWSET_SIZE 5 int TbSelectUsingFetchScrollColWise( SQLHANDLE) ; int TbSelectUsingFetchScrollRowWise( SQLHANDLE) ; int TbSelectUsingSQLBulkOperations( SQLHANDLE) ; /* types of select */ int TbSubSelect( SQLHANDLE) ; int TbJoinSelect( SQLHANDLE) ; int TbGroupingSetsSelect( SQLHANDLE) ; int TbCubeSelect( SQLHANDLE) ; int TbRollupSelect( SQLHANDLE) ; int TbRecursiveSelect( SQLHANDLE) ; /******************************************************************* ** main *******************************************************************/ int main( int argc, char * argv[] ) { SQLRETURN sqlrc = SQL_SUCCESS; int rc = 0; SQLHANDLE henv; /* environment handle */ SQLHANDLE hdbc; /* connection handles */ char dbAlias[SQL_MAX_DSN_LENGTH + 1] ; char user[MAX_UID_LENGTH + 1] ; char pswd[MAX_PWD_LENGTH + 1] ; /* checks the command line arguments */ rc = CmdLineArgsCheck1( argc, argv, dbAlias, user, pswd ); if ( rc != 0 ) return( rc ) ; printf("\n\nTABLES: HOW TO READ TABLES.\n"); /* initialize the CLI application */ rc = CLIAppInit( dbAlias, user, pswd, &henv, &hdbc, (SQLPOINTER)SQL_AUTOCOMMIT_ON); if ( rc != 0 ) return( rc ) ; /*****************************************************************/ printf("\n****** METHODS TO PERFORM SELECT *******************\n"); /*****************************************************************/ /* two basic selects */ rc = TbBasicSelectUsingFetchAndBindCol( hdbc) ; rc = TbBasicSelectUsingFetchAndGetData( hdbc) ; /* select on system tables */ rc = SysTbSelect( hdbc) ; /* select with parameters */ rc = TbSelectWithParam( hdbc) ; /* select with unknown output columns */ rc = TbSelectWithUnknownOutCols( hdbc) ; /* select using SQLFetchScroll with column-wise binding */ rc = TbSelectUsingFetchScrollColWise( hdbc) ; /* select using SQLFetchScroll with row-wise binding */ rc = TbSelectUsingFetchScrollRowWise( hdbc) ; /* select using SQLBulkOperations */ /* rc = TbSelectUsingSQLBulkOperations( hdbc) ; */ /*****************************************************************/ printf("\n****** TYPES OF SELECT *****************************\n"); /*****************************************************************/ /* complete subselect */ /* rc = TbSubSelect( hdbc) ; */ /* recursive select */ /* rc = TbRecursiveSelect( hdbc) ; */ /* terminate the CLI application */ rc = CLIAppTerm( &henv, &hdbc, dbAlias); return( rc ) ; } /* end main */ /****************************************************************************** ** TbBasicSelectUsingFetchAndBindCol - no more comments ******************************************************************************/ int TbBasicSelectUsingFetchAndBindCol( SQLHANDLE hdbc) { SQLRETURN sqlrc = SQL_SUCCESS; int rc = 0; SQLHANDLE hstmt ; /* statement handle */ SQLCHAR * stmt = ( SQLCHAR * ) "SELECT deptnumb, location FROM org"; struct { SQLINTEGER ind ; SQLSMALLINT val ; } deptnumb ; /* variable to be bound to the DEPTNUMB column */ struct { SQLINTEGER ind ; SQLCHAR val[15] ; } location ; /* variable to be bound to the LOCATION column */ printf("\nUSE THE CLI FUNCTIONS\n"); printf("-SQLSetConnectAttr\n-SQLAllocHandle\n"); printf("-SQLExecDirect\n-SQLBindCol\n"); printf("-SQLFetch\n-SQLFreeHandle\n"); printf("TO PERFORM A BASIC SELECT:\n"); /* set AUTOCOMMIT on */ sqlrc = SQLSetConnectAttr( hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_NTS) ; DBC_HANDLE_CHECK( hdbc, sqlrc); /* allocate a statement handle */ sqlrc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; DBC_HANDLE_CHECK( hdbc, sqlrc); /* execute directly the statement */ printf("\n Execute directly the statement.\n"); printf(" %s\n", stmt); sqlrc = SQLExecDirect( hstmt, stmt, SQL_NTS ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); /* bind columns to variables */ sqlrc = SQLBindCol( hstmt, 1, SQL_C_SHORT, &deptnumb.val, 0, &deptnumb.ind); STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLBindCol( hstmt, 2, SQL_C_CHAR, location.val, 15, &location.ind); STMT_HANDLE_CHECK( hstmt, sqlrc); /* fetch each row, and display */ printf(" Fetch each row and dispaly.\n"); printf(" DEPTNUMB LOCATION \n" ) ; printf(" -------- -------------\n" ) ; sqlrc = SQLFetch( hstmt ); STMT_HANDLE_CHECK( hstmt, sqlrc); if (sqlrc == SQL_NO_DATA_FOUND) { printf("\n Data not found.\n"); } while (sqlrc != SQL_NO_DATA_FOUND) { printf( " %-8d %-14.14s \n", deptnumb.val, location.val ) ; sqlrc = SQLFetch( hstmt ); STMT_HANDLE_CHECK( hstmt, sqlrc); } /* free the statement handle */ sqlrc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); return(rc); } /****************************************************************************** ** TbBasicSelectUsingFetchAndGetData - no more comments ******************************************************************************/ int TbBasicSelectUsingFetchAndGetData( SQLHANDLE hdbc) { SQLRETURN sqlrc = SQL_SUCCESS; int rc = 0; SQLHANDLE hstmt ; /* statement handle */ SQLCHAR * stmt = ( SQLCHAR * ) "SELECT deptnumb, location FROM org"; struct { SQLINTEGER ind ; SQLSMALLINT val ; } deptnumb ; /* variable to get data from the DEPTNUMB column */ struct { SQLINTEGER ind ; SQLCHAR val[15] ; } location ; /* variable to get data from the LOCATION column */ printf("\nUSE THE CLI FUNCTIONS\n"); printf("-SQLSetConnectAttr\n-SQLAllocHandle\n"); printf("-SQLExecDirect\n-SQLFetch\n"); printf("-SQLGetData\n-SQLFreeHandle\n"); printf("TO PERFORM A BASIC SELECT:\n"); /* set AUTOCOMMIT on */ sqlrc = SQLSetConnectAttr( hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_NTS) ; DBC_HANDLE_CHECK( hdbc, sqlrc); /* allocate a statement handle */ sqlrc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; DBC_HANDLE_CHECK( hdbc, sqlrc); /* execute directly the statement */ printf("\n Execute directly the statement.\n"); printf(" %s\n", stmt); sqlrc = SQLExecDirect( hstmt, stmt, SQL_NTS ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); /* fetch each row, and display */ printf(" Fetch each row and dispaly.\n"); printf(" DEPTNUMB LOCATION \n" ) ; printf(" -------- -------------\n" ) ; sqlrc = SQLFetch( hstmt ); STMT_HANDLE_CHECK( hstmt, sqlrc); if (sqlrc == SQL_NO_DATA_FOUND) { printf("\n Data not found.\n"); } while (sqlrc != SQL_NO_DATA_FOUND) { /* use SQLGetData to get the results */ sqlrc = SQLGetData( hstmt, 1, SQL_C_SHORT, &deptnumb.val, 0, &deptnumb.ind ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLGetData( hstmt, 2, SQL_C_CHAR, location.val, 15, &location.ind ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); /* display */ printf( " %-8d %-14.14s \n", deptnumb.val, location.val ) ; sqlrc = SQLFetch( hstmt ); STMT_HANDLE_CHECK( hstmt, sqlrc); } /* free the statement handle */ sqlrc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); return(rc); } /****************************************************************************** ** SysTbSelect - perform select on system tables ******************************************************************************/ int SysTbSelect( SQLHANDLE hdbc) { SQLRETURN sqlrc = SQL_SUCCESS; int rc = 0; SQLHANDLE hstmt ; /* statement handle */ struct { SQLINTEGER ind ; SQLCHAR val[129] ; } tbQualifier, tbSchema, tbName, tbType; struct { SQLINTEGER ind ; SQLCHAR val[255] ; } tbRemarks; SQLCHAR tbSchemaPattern[] = "%"; SQLCHAR tbNamePattern[] = "ST%"; /* all the tables starting with ST */ printf("\nThere are some CLI functions that basically \n"); printf("perform SELECT on SYSTEM TABLES.\n"); printf("They return info stored in the system tables,\n"); printf("about objects in the database.\n"); printf("They are:\n"); printf("-SQLColumnPrivileges\n-SQLColumns\n-SQLForeignKeys\n"); printf("-SQLPrimaryKeys\n-SQLProcedureColumns\n-SQLProcedures\n"); printf("-SQLSpecialColumns\n-SQLStatistics\n"); printf("-SQLTablePrivileges\n-SQLTables\n"); printf("\nUSE THE CLI FUNCTIONS\n"); printf("-SQLSetConnectAttr\n-SQLAllocHandle\n"); printf("-SQLTables\n-SQLBindCol\n"); printf("-SQLFetch\n-SQLFreeHandle\n"); printf("TO SHOW HOW TO USE THE CLI FUNCTION SQLTables, FOR INSTANCE:\n"); /* set AUTOCOMMIT on */ sqlrc = SQLSetConnectAttr( hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_NTS) ; DBC_HANDLE_CHECK( hdbc, sqlrc); /* allocate a statement handle */ sqlrc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; DBC_HANDLE_CHECK( hdbc, sqlrc); /* call SQLTables */ printf("\n Call SQLTables.\n"); sqlrc = SQLTables( hstmt, NULL, 0, tbSchemaPattern, SQL_NTS, tbNamePattern, SQL_NTS, NULL, 0); STMT_HANDLE_CHECK( hstmt, sqlrc); /* bind columns to variables */ sqlrc = SQLBindCol( hstmt, 1, SQL_C_CHAR, tbQualifier.val, 129, &tbQualifier.ind ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLBindCol( hstmt, 2, SQL_C_CHAR, tbSchema.val, 129, &tbSchema.ind ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLBindCol( hstmt, 3, SQL_C_CHAR, tbName.val, 129, &tbName.ind ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLBindCol( hstmt, 4, SQL_C_CHAR, tbType.val, 129, &tbType.ind ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLBindCol( hstmt, 5, SQL_C_CHAR, tbRemarks.val, 255, &tbRemarks.ind ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); /* fetch each row, and display */ printf(" Fetch each row and dispaly.\n"); printf(" TABLE SCHEMA TABLE_NAME TABLE_TYPE\n"); printf(" -------------- -------------- ----------\n"); sqlrc = SQLFetch( hstmt ); STMT_HANDLE_CHECK( hstmt, sqlrc); if (sqlrc == SQL_NO_DATA_FOUND) { printf("\n Data not found.\n"); } while (sqlrc != SQL_NO_DATA_FOUND) { printf(" %-14s %-14s %-11s\n", tbSchema.val, tbName.val, tbType.val); if (tbRemarks.ind > 0) { printf(" (Remarks ) %s\n", tbRemarks.val); } sqlrc = SQLFetch( hstmt ); STMT_HANDLE_CHECK( hstmt, sqlrc); } /* free the statement handle */ sqlrc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); return(rc); } /****************************************************************************** ** TbSelectWithParam - how to perform select with parameters ******************************************************************************/ int TbSelectWithParam( SQLHANDLE hdbc) { SQLRETURN sqlrc = SQL_SUCCESS; int rc = 0; SQLHANDLE hstmt ; /* statement handle */ SQLCHAR * stmt = ( SQLCHAR * ) "SELECT deptnumb, location FROM org WHERE division = ?"; char divisionParam[15] ; struct { SQLINTEGER ind ; SQLSMALLINT val ; } deptnumb ; /* variable to be bound to the DEPTNUMB column */ struct { SQLINTEGER ind ; SQLCHAR val[15] ; } location ; /* variable to be bound to the LOCATION column */ printf("\nUSE THE CLI FUNCTIONS\n"); printf("-SQLSetConnectAttr\n-SQLAllocHandle\n"); printf("-SQLPrepare\n-SQLBindParameter\n"); printf("-SQLExecute\n-SQLBindCol\n"); printf("-SQLFetch\n-SQLFreeHandle\n"); printf("TO PERFORM A SELECT WITH PARAMETERS:\n"); /* set AUTOCOMMIT on */ sqlrc = SQLSetConnectAttr( hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_NTS) ; DBC_HANDLE_CHECK( hdbc, sqlrc); /* allocate a statement handle */ sqlrc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; DBC_HANDLE_CHECK( hdbc, sqlrc); /* prepare the statement */ printf("\n Prepare the statement\n"); printf(" %s\n", stmt); sqlrc = SQLPrepare( hstmt, stmt, SQL_NTS ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); /* bind divisionParam to the statement */ printf(" Bind divisionParam to the statement\n"); printf(" %s\n", stmt); sqlrc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 15, 0, divisionParam, 15, NULL); STMT_HANDLE_CHECK( hstmt, sqlrc); /* execute the statement for divisionParam = Eastern */ printf(" Execute the prepared statement for\n"); printf(" divisionParam = 'Eastern'\n"); strcpy( divisionParam, "Eastern"); sqlrc = SQLExecute( hstmt ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); /* bind columns to variables */ sqlrc = SQLBindCol( hstmt, 1, SQL_C_SHORT, &deptnumb.val, 0, &deptnumb.ind); STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLBindCol( hstmt, 2, SQL_C_CHAR, location.val, 15, &location.ind); STMT_HANDLE_CHECK( hstmt, sqlrc); /* fetch each row, and display */ printf(" Fetch each row and dispaly.\n"); printf(" DEPTNUMB LOCATION \n" ) ; printf(" -------- -------------\n" ) ; sqlrc = SQLFetch( hstmt ); STMT_HANDLE_CHECK( hstmt, sqlrc); if (sqlrc == SQL_NO_DATA_FOUND) { printf("\n Data not found.\n"); } while (sqlrc != SQL_NO_DATA_FOUND) { printf( " %-8d %-14.14s \n", deptnumb.val, location.val ) ; sqlrc = SQLFetch( hstmt ); STMT_HANDLE_CHECK( hstmt, sqlrc); } /* free the statement handle */ sqlrc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); return(rc); } /****************************************************************************** ** TbSelectWithUnknownOutCols - select with unknown output columns ** at compile time ******************************************************************************/ int TbSelectWithUnknownOutCols( SQLHANDLE hdbc) { SQLRETURN sqlrc = SQL_SUCCESS; int rc = 0; SQLHANDLE hstmt ; /* statement handle */ SQLCHAR * stmt = ( SQLCHAR * ) "SELECT * FROM org"; SQLSMALLINT i ; /* index */ SQLSMALLINT nResultCols ; /* variable for SQLNumResultCols */ SQLCHAR colName[32] ; /* variables for SQLDescribeCol */ SQLSMALLINT colNameLen ; SQLSMALLINT colType ; SQLUINTEGER colSize ; SQLSMALLINT colScale ; SQLINTEGER colDataDisplaySize ; /* the max. size of the data */ SQLINTEGER colDisplaySize[MAX_COLUMNS] ; /* the max. size of the column */ struct { SQLCHAR * buff; SQLINTEGER len; SQLINTEGER buffLen; } outData[MAX_COLUMNS]; /* var. to read the results */ printf("\nUSE THE CLI FUNCTIONS\n"); printf("-SQLSetConnectAttr\n-SQLAllocHandle\n-SQLExecDirect\n"); printf("-SQLNumResultCols\n-SQLDescribeCol\n-SQLSetColAttribute\n"); printf("-SQLBindCol\n-SQLFetch\n-SQLFreeHandle\n"); printf("TO PERFORM A SELECT WITH UNKNOWN OUTPUT COLUMNS\n"); printf("AT COMPILE TIME:\n"); /* set AUTOCOMMIT on */ sqlrc = SQLSetConnectAttr( hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_NTS) ; DBC_HANDLE_CHECK( hdbc, sqlrc); /* allocate a statement handle */ sqlrc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; DBC_HANDLE_CHECK( hdbc, sqlrc); /* execute directly the statement */ printf("\n Execute directly the statement\n"); printf(" %s.\n", stmt); sqlrc = SQLExecDirect( hstmt, stmt, SQL_NTS ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); printf(" Identify the output columns, then \n"); printf(" fetch each row and display.\n"); /* identify the output columns */ sqlrc = SQLNumResultCols( hstmt, &nResultCols ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); printf("\n "); for ( i = 0; i < nResultCols; i++ ) { sqlrc = SQLDescribeCol( hstmt, ( SQLSMALLINT ) ( i + 1 ), colName, sizeof(colName), &colNameLen, &colType, &colSize, &colScale, NULL ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); /* get display size for column */ sqlrc = SQLColAttribute( hstmt, ( SQLSMALLINT ) ( i + 1 ), SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL, &colDataDisplaySize ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); /* set "column display size" to max of "column data display size", and "column name length". Plus at least one space between columns. */ colDisplaySize[i] = max( colDataDisplaySize, colNameLen ) + 1 ; /* print the column name */ printf( "%-*.*s", (int) colDisplaySize[i], (int) colDisplaySize[i], colName ) ; /* set "output data buffer length" to "column data display size". Plus one byte for null terminator. */ outData[i].buffLen = colDataDisplaySize + 1; /* allocate memory to bind column */ outData[i].buff = ( SQLCHAR * ) malloc( (int) outData[i].buffLen ) ; /* bind columns to program vars, converting all types to CHAR */ sqlrc = SQLBindCol( hstmt, ( SQLSMALLINT ) ( i + 1 ), SQL_C_CHAR, outData[i].buff, outData[i].buffLen, &outData[i].len ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); } printf( "\n" ) ; /* fetch each row and display */ sqlrc = SQLFetch( hstmt ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); if (sqlrc == SQL_NO_DATA_FOUND) { printf("\nData not found.\n"); } while ( sqlrc != SQL_NO_DATA_FOUND ) { printf(" "); for ( i = 0; i < nResultCols; i++ ) { /* check for NULL data */ if ( outData[i].len == SQL_NULL_DATA ) { printf( "%-*.*s", (int) colDisplaySize[i], (int) colDisplaySize[i], "NULL" ) ; } else { /* print outData for this column */ printf( "%-*.*s", (int) colDisplaySize[i], (int) colDisplaySize[i], outData[i].buff ) ; } } /* for all columns in this row */ printf("\n"); sqlrc = SQLFetch( hstmt ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); } /* while rows to fetch */ /* free data buffers */ for ( i = 0; i < nResultCols; i++ ) { free( outData[i].buff ) ; } /* free the statement handle */ sqlrc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); return(rc); } /****************************************************************************** ** TbSelectUsingFetchScrollColWise - no more comments ******************************************************************************/ int TbSelectUsingFetchScrollColWise( SQLHANDLE hdbc) { SQLRETURN sqlrc = SQL_SUCCESS; int rc = 0; SQLHANDLE hstmt ; /* statement handle */ SQLHANDLE hstmtTable ; /* to create a test table */ SQLINTEGER rowNb; SQLCHAR stmtInsert[100]; SQLUINTEGER rowsFetchedNb; SQLUSMALLINT rowStatus[ROWSET_SIZE]; static char ROWSTATVALUE[][26] = { "SQL_ROW_SUCCESS", \ "SQL_ROW_SUCCESS_WITH_INFO", \ "SQL_ROW_ERROR", \ "SQL_ROW_NOROW" }; int i; struct { SQLINTEGER ind[ROWSET_SIZE] ; SQLCHAR val[ROWSET_SIZE][15] ; } col1, col2 ; /* variables to be bound to columns */ struct { SQLINTEGER ind ; SQLINTEGER val[4] ; } bookmark ; printf("\nUSE THE CLI FUNCTIONS\n"); printf("-SQLSetConnectAttr\n-SQLAllocHandle\n"); printf("-SQLExecDirect\n-SQLSetStmtAttr\n-SQLBindCol\n"); printf("-SQLFetchScroll\n-SQLSetPos\n"); printf("-SQLGetData\n-SQLFreeHandle\n"); printf("TO DEMONSTRATE SCROLLABLE CURSORS\n"); printf("USING COLUMN-WISE BINDING:\n"); /* set AUTOCOMMIT on */ sqlrc = SQLSetConnectAttr( hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_NTS) ; DBC_HANDLE_CHECK( hdbc, sqlrc); /* allocate a statement handle */ sqlrc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmtTable ) ; DBC_HANDLE_CHECK( hdbc, sqlrc); /* create a table with 30 rows */ printf("\n Create a table with 2 columns and 30 rows.\n"); sqlrc = SQLExecDirect( hstmtTable, (UCHAR*)"CREATE TABLE fetchScrollTable ( col1 CHAR(14), col2 CHAR(14))", SQL_NTS ) ; STMT_HANDLE_CHECK( hstmtTable, sqlrc); for( rowNb = 1; rowNb <= 30; rowNb++) { sprintf((char*) stmtInsert, "INSERT INTO fetchScrollTable VALUES ( 'row%d_col1', 'row%d_col2')", rowNb, rowNb); sqlrc = SQLExecDirect( hstmtTable, stmtInsert, SQL_NTS ) ; STMT_HANDLE_CHECK( hstmtTable, sqlrc); } /* allocate a statement handle for FetchScroll */ sqlrc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; DBC_HANDLE_CHECK( hdbc, sqlrc); /* set the required statement attributes */ printf(" Set the required statement attributes.\n"); sqlrc = SQLSetStmtAttr( hstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) ROWSET_SIZE, 0); STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLSetStmtAttr( hstmt, SQL_ATTR_ROW_BIND_TYPE, SQL_BIND_BY_COLUMN, 0); STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLSetStmtAttr( hstmt, SQL_ATTR_ROWS_FETCHED_PTR, &rowsFetchedNb, 0); STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLSetStmtAttr( hstmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_STATIC, 0); STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLSetStmtAttr( hstmt, SQL_ATTR_USE_BOOKMARKS, (SQLPOINTER) SQL_UB_VARIABLE, 0); STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLSetStmtAttr( hstmt, SQL_ATTR_ROW_STATUS_PTR, (SQLPOINTER) rowStatus, 0); STMT_HANDLE_CHECK( hstmt, sqlrc); /* select everything from the test table */ printf(" Select all 30 rows from the test table.\n"); sqlrc = SQLExecDirect( hstmt, (SQLCHAR*)"SELECT * FROM fetchScrollTable", SQL_NTS ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); /* bind columns to variables */ sqlrc = SQLBindCol( hstmt, 1, SQL_C_CHAR, col1.val, 15, col1.ind); STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLBindCol( hstmt, 2, SQL_C_CHAR, col2.val, 15, col2.ind); STMT_HANDLE_CHECK( hstmt, sqlrc); /* SQLFetchScroll with SQL_FETCH_ABSOLUTE at row 15 */ printf("\n SQLFetchScroll with SQL_FETCH_ABSOLUTE at row 15.\n"); printf(" COL1 COL2 \n" ) ; printf(" ------------ -------------\n" ) ; sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_ABSOLUTE, 15 ); STMT_HANDLE_CHECK( hstmt, sqlrc); if (sqlrc == SQL_NO_DATA_FOUND) { printf("\n Data not found.\n"); } for ( i = 0; i < rowsFetchedNb; i++) { printf(" %-14s%-14s\n", col1.val[i], col2.val[i]); } /* output the Row Status Array if the complete rowset was not returned. */ if ( rowsFetchedNb != ROWSET_SIZE) { printf(" Previous rowset was not full:\n"); for (i = 0; i < ROWSET_SIZE; i++) { printf(" Row Status Array[%i] = %s\n", i, ROWSTATVALUE[rowStatus[i]]); } } /* fetch the rowset: row15, row16, row17, row18, row19 */ printf("\n Fetch the rowset: row15, row16, row17, row18, row19.\n"); sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_ABSOLUTE, 15 ); STMT_HANDLE_CHECK( hstmt, sqlrc); /* SQLFetchScroll with SQL_FETCH_NEXT */ printf(" SQLFetchScroll with SQL_FETCH_NEXT.\n"); printf(" COL1 COL2 \n" ) ; printf(" ------------ -------------\n" ) ; sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_NEXT, 0 ); STMT_HANDLE_CHECK( hstmt, sqlrc); if (sqlrc == SQL_NO_DATA_FOUND) { printf("\n Data not found.\n"); } for ( i = 0; i < rowsFetchedNb; i++) { printf(" %-14s%-14s\n", col1.val[i], col2.val[i]); } /* output the Row Status Array if the complete rowset was not returned. */ if ( rowsFetchedNb != ROWSET_SIZE) { printf(" Previous rowset was not full:\n"); for (i = 0; i < ROWSET_SIZE; i++) { printf(" Row Status Array[%i] = %s\n", i, ROWSTATVALUE[rowStatus[i]]); } } /* fetch the rowset: row15, row16, row17, row18, row19 */ printf("\n Fetch the rowset: row15, row16, row17, row18, row19.\n"); sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_ABSOLUTE, 15 ); STMT_HANDLE_CHECK( hstmt, sqlrc); /* SQLFetchScroll with SQL_FETCH_PRIOR */ printf(" SQLFetchScroll with SQL_FETCH_PRIOR.\n"); printf(" COL1 COL2 \n" ) ; printf(" ------------ -------------\n" ) ; sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_PRIOR, 0 ); STMT_HANDLE_CHECK( hstmt, sqlrc); if (sqlrc == SQL_NO_DATA_FOUND) { printf("\n Data not found.\n"); } for ( i = 0; i < rowsFetchedNb; i++) { printf(" %-14s%-14s\n", col1.val[i], col2.val[i]); } /* output the Row Status Array if the complete rowset was not returned. */ if ( rowsFetchedNb != ROWSET_SIZE) { printf(" Previous rowset was not full:\n"); for (i = 0; i < ROWSET_SIZE; i++) { printf(" Row Status Array[%i] = %s\n", i, ROWSTATVALUE[rowStatus[i]]); } } /* fetch the rowset: row15, row16, row17, row18, row19 */ printf("\n Fetch the rowset: row15, row16, row17, row18, row19.\n"); sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_ABSOLUTE, 15 ); STMT_HANDLE_CHECK( hstmt, sqlrc); /* SQLFetchScroll with SQL_FETCH_FIRST */ printf(" SQLFetchScroll with SQL_FETCH_FIRST.\n"); printf(" COL1 COL2 \n" ) ; printf(" ------------ -------------\n" ) ; sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_FIRST, 0 ); STMT_HANDLE_CHECK( hstmt, sqlrc); if (sqlrc == SQL_NO_DATA_FOUND) { printf("\n Data not found.\n"); } for ( i = 0; i < rowsFetchedNb; i++) { printf(" %-14s%-14s\n", col1.val[i], col2.val[i]); } /* output the Row Status Array if the complete rowset was not returned. */ if ( rowsFetchedNb != ROWSET_SIZE) { printf(" Previous rowset was not full:\n"); for (i = 0; i < ROWSET_SIZE; i++) { printf(" Row Status Array[%i] = %s\n", i, ROWSTATVALUE[rowStatus[i]]); } } /* fetch the rowset: row15, row16, row17, row18, row19 */ printf("\n Fetch the rowset: row15, row16, row17, row18, row19.\n"); sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_ABSOLUTE, 15 ); STMT_HANDLE_CHECK( hstmt, sqlrc); /* SQLFetchScroll with SQL_FETCH_LAST */ printf(" SQLFetchScroll with SQL_FETCH_LAST.\n"); printf(" COL1 COL2 \n" ) ; printf(" ------------ -------------\n" ) ; sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_LAST, 0 ); STMT_HANDLE_CHECK( hstmt, sqlrc); if (sqlrc == SQL_NO_DATA_FOUND) { printf("\n Data not found.\n"); } for ( i = 0; i < rowsFetchedNb; i++) { printf(" %-14s%-14s\n", col1.val[i], col2.val[i]); } /* output the Row Status Array if the complete rowset was not returned. */ if ( rowsFetchedNb != ROWSET_SIZE) { printf(" Previous rowset was not full:\n"); for (i = 0; i < ROWSET_SIZE; i++) { printf(" Row Status Array[%i] = %s\n", i, ROWSTATVALUE[rowStatus[i]]); } } /* fetch the rowset: row15, row16, row17, row18, row19 */ printf("\n Fetch the rowset: row15, row16, row17, row18, row19.\n"); sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_ABSOLUTE, 15 ); STMT_HANDLE_CHECK( hstmt, sqlrc); /* SQLFetchScroll with SQL_FETCH_RELATIVE offset 3 */ printf(" SQLFetchScroll with SQL_FETCH_RELATIVE offset 3.\n"); printf(" COL1 COL2 \n" ) ; printf(" ------------ -------------\n" ) ; sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_RELATIVE, 3 ); STMT_HANDLE_CHECK( hstmt, sqlrc); if (sqlrc == SQL_NO_DATA_FOUND) { printf("\n Data not found.\n"); } for ( i = 0; i < rowsFetchedNb; i++) { printf(" %-14s%-14s\n", col1.val[i], col2.val[i]); } /* output the Row Status Array if the complete rowset was not returned. */ if ( rowsFetchedNb != ROWSET_SIZE) { printf(" Previous rowset was not full:\n"); for (i = 0; i < ROWSET_SIZE; i++) { printf(" Row Status Array[%i] = %s\n", i, ROWSTATVALUE[rowStatus[i]]); } } /* set the bookmark at the row 17 */ printf("\n Set the bookmark at the row 17.\n"); sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_ABSOLUTE, 15 ); STMT_HANDLE_CHECK( hstmt, sqlrc); /* 1->15, 2->16, 3->17*/ sqlrc = SQLSetPos( hstmt, 3, SQL_POSITION, SQL_LOCK_NO_CHANGE); STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLGetData(hstmt, 0, SQL_C_LONG, bookmark.val, 4, &bookmark.ind); STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLSetStmtAttr( hstmt, SQL_ATTR_FETCH_BOOKMARK_PTR, (SQLPOINTER) bookmark.val, 0); STMT_HANDLE_CHECK( hstmt, sqlrc); /* SQLFetchScroll with SQL_FETCH_BOOKMARK offset 4 */ printf(" SQLFetchScroll with SQL_FETCH_BOOKMARK offset 4.\n"); printf(" COL1 COL2 \n" ) ; printf(" ------------ -------------\n" ) ; sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_BOOKMARK, 4 ); STMT_HANDLE_CHECK( hstmt, sqlrc); if (sqlrc == SQL_NO_DATA_FOUND) { printf("\n Data not found.\n"); } for ( i = 0; i < rowsFetchedNb; i++) { printf(" %-14s%-14s\n", col1.val[i], col2.val[i]); } /* output the Row Status Array if the complete rowset was not returned. */ if ( rowsFetchedNb != ROWSET_SIZE) { printf(" Previous rowset was not full:\n"); for (i = 0; i < ROWSET_SIZE; i++) { printf(" Row Status Array[%i] = %s\n", i, ROWSTATVALUE[rowStatus[i]]); } } /* free the statement handle */ sqlrc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); /* drop the test table */ printf("\n Drop the test table.\n"); sqlrc = SQLExecDirect( hstmtTable, (SQLCHAR *)"DROP TABLE fetchScrollTable ", SQL_NTS ) ; STMT_HANDLE_CHECK( hstmtTable, sqlrc); /* free the statement handle */ sqlrc = SQLFreeHandle( SQL_HANDLE_STMT, hstmtTable ) ; STMT_HANDLE_CHECK( hstmtTable, sqlrc); return(rc); } /****************************************************************************** ** TbSelectUsingFetchScrollRowWise - no more comments ******************************************************************************/ int TbSelectUsingFetchScrollRowWise( SQLHANDLE hdbc) { SQLRETURN sqlrc = SQL_SUCCESS; int rc = 0; SQLHANDLE hstmt ; /* statement handle */ SQLHANDLE hstmtTable ; /* to create a test table */ SQLINTEGER rowNb; SQLCHAR stmtInsert[100]; SQLUINTEGER rowsFetchedNb; SQLUSMALLINT rowStatus[ROWSET_SIZE]; static char ROWSTATVALUE[][26] = { "SQL_ROW_SUCCESS", \ "SQL_ROW_SUCCESS_WITH_INFO", \ "SQL_ROW_ERROR", \ "SQL_ROW_NOROW" }; int i; struct { SQLINTEGER col1_ind ; SQLCHAR col1_val[15] ; SQLINTEGER col2_ind ; SQLCHAR col2_val[15] ; } rowset[ROWSET_SIZE]; /* variables to be bound to columns */ struct { SQLINTEGER ind ; SQLINTEGER val[4] ; } bookmark ; printf("\nUSE THE CLI FUNCTIONS\n"); printf("-SQLSetConnectAttr\n-SQLAllocHandle\n"); printf("-SQLExecDirect\n-SQLSetStmtAttr\n-SQLBindCol\n"); printf("-SQLFetchScroll\n-SQLSetPos\n"); printf("-SQLGetData\n-SQLFreeHandle\n"); printf("TO DEMONSTRATE SCROLLABLE CURSORS\n"); printf("USING ROW-WISE BINDING:\n"); /* set AUTOCOMMIT on */ sqlrc = SQLSetConnectAttr( hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_NTS) ; DBC_HANDLE_CHECK( hdbc, sqlrc); /* allocate a statement handle */ sqlrc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmtTable ) ; DBC_HANDLE_CHECK( hdbc, sqlrc); /* create a table with 30 rows */ printf("\n Create a table with 2 columns and 30 rows.\n"); sqlrc = SQLExecDirect( hstmtTable, (SQLCHAR*)"CREATE TABLE fetchScrollTable ( col1 CHAR(14), col2 CHAR(14))", SQL_NTS ) ; STMT_HANDLE_CHECK( hstmtTable, sqlrc); for( rowNb = 1; rowNb <= 30; rowNb++) { sprintf( (char *)stmtInsert, "INSERT INTO fetchScrollTable VALUES ( 'row%d_col1', 'row%d_col2')", rowNb, rowNb); sqlrc = SQLExecDirect( hstmtTable, stmtInsert, SQL_NTS ) ; STMT_HANDLE_CHECK( hstmtTable, sqlrc); } /* allocate a statement handle for FetchScroll */ sqlrc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; DBC_HANDLE_CHECK( hdbc, sqlrc); /* set the required statement attributes */ printf(" Set the required statement attributes.\n"); sqlrc = SQLSetStmtAttr( hstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) ROWSET_SIZE, 0); STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLSetStmtAttr( hstmt, SQL_ATTR_ROW_BIND_TYPE, (SQLPOINTER) ( sizeof(rowset)/ROWSET_SIZE), 0); STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLSetStmtAttr( hstmt, SQL_ATTR_ROWS_FETCHED_PTR, &rowsFetchedNb, 0); STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLSetStmtAttr( hstmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_STATIC, 0); STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLSetStmtAttr( hstmt, SQL_ATTR_USE_BOOKMARKS, (SQLPOINTER) SQL_UB_VARIABLE, 0); STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLSetStmtAttr( hstmt, SQL_ATTR_ROW_STATUS_PTR, (SQLPOINTER) rowStatus, 0); STMT_HANDLE_CHECK( hstmt, sqlrc); /* select everything from the test table */ printf(" Select all 30 rows from the test table.\n"); sqlrc = SQLExecDirect( hstmt, (SQLCHAR*)"SELECT * FROM fetchScrollTable", SQL_NTS ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); /* bind columns to variables */ sqlrc = SQLBindCol( hstmt, 1, SQL_C_CHAR, (SQLPOINTER) rowset[0].col1_val, 15, &rowset[0].col1_ind); STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLBindCol( hstmt, 2, SQL_C_CHAR, (SQLPOINTER) rowset[0].col2_val, 15, &rowset[0].col2_ind); STMT_HANDLE_CHECK( hstmt, sqlrc); /* SQLFetchScroll with SQL_FETCH_ABSOLUTE at row 15 */ printf("\n SQLFetchScroll with SQL_FETCH_ABSOLUTE at row 15.\n"); printf(" COL1 COL2 \n" ) ; printf(" ------------ -------------\n" ) ; sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_ABSOLUTE, 15 ); STMT_HANDLE_CHECK( hstmt, sqlrc); if (sqlrc == SQL_NO_DATA_FOUND) { printf("\n Data not found.\n"); } for ( i = 0; i < rowsFetchedNb; i++) { printf(" %-14s%-14s\n", rowset[i].col1_val, rowset[i].col2_val); } /* output the Row Status Array if the complete rowset was not returned. */ if ( rowsFetchedNb != ROWSET_SIZE) { printf(" Previous rowset was not full:\n"); for (i = 0; i < ROWSET_SIZE; i++) { printf(" Row Status Array[%i] = %s\n", i, ROWSTATVALUE[rowStatus[i]]); } } /* fetch the rowset: row15, row16, row17, row18, row19 */ printf("\n Fetch the rowset: row15, row16, row17, row18, row19.\n"); sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_ABSOLUTE, 15 ); STMT_HANDLE_CHECK( hstmt, sqlrc); /* SQLFetchScroll with SQL_FETCH_NEXT */ printf(" SQLFetchScroll with SQL_FETCH_NEXT.\n"); printf(" COL1 COL2 \n" ) ; printf(" ------------ -------------\n" ) ; sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_NEXT, 0 ); STMT_HANDLE_CHECK( hstmt, sqlrc); if (sqlrc == SQL_NO_DATA_FOUND) { printf("\n Data not found.\n"); } for ( i = 0; i < rowsFetchedNb; i++) { printf(" %-14s%-14s\n", rowset[i].col1_val, rowset[i].col2_val); } /* output the Row Status Array if the complete rowset was not returned. */ if ( rowsFetchedNb != ROWSET_SIZE) { printf(" Previous rowset was not full:\n"); for (i = 0; i < ROWSET_SIZE; i++) { printf(" Row Status Array[%i] = %s\n", i, ROWSTATVALUE[rowStatus[i]]); } } /* fetch the rowset: row15, row16, row17, row18, row19 */ printf("\n Fetch the rowset: row15, row16, row17, row18, row19.\n"); sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_ABSOLUTE, 15 ); STMT_HANDLE_CHECK( hstmt, sqlrc); /* SQLFetchScroll with SQL_FETCH_PRIOR */ printf(" SQLFetchScroll with SQL_FETCH_PRIOR.\n"); printf(" COL1 COL2 \n" ) ; printf(" ------------ -------------\n" ) ; sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_PRIOR, 0 ); STMT_HANDLE_CHECK( hstmt, sqlrc); if (sqlrc == SQL_NO_DATA_FOUND) { printf("\n Data not found.\n"); } for ( i = 0; i < rowsFetchedNb; i++) { printf(" %-14s%-14s\n", rowset[i].col1_val, rowset[i].col2_val); } /* output the Row Status Array if the complete rowset was not returned. */ if ( rowsFetchedNb != ROWSET_SIZE) { printf(" Previous rowset was not full:\n"); for (i = 0; i < ROWSET_SIZE; i++) { printf(" Row Status Array[%i] = %s\n", i, ROWSTATVALUE[rowStatus[i]]); } } /* fetch the rowset: row15, row16, row17, row18, row19 */ printf("\n Fetch the rowset: row15, row16, row17, row18, row19.\n"); sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_ABSOLUTE, 15 ); STMT_HANDLE_CHECK( hstmt, sqlrc); /* SQLFetchScroll with SQL_FETCH_FIRST */ printf(" SQLFetchScroll with SQL_FETCH_FIRST.\n"); printf(" COL1 COL2 \n" ) ; printf(" ------------ -------------\n" ) ; sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_FIRST, 0 ); STMT_HANDLE_CHECK( hstmt, sqlrc); if (sqlrc == SQL_NO_DATA_FOUND) { printf("\n Data not found.\n"); } for ( i = 0; i < rowsFetchedNb; i++) { printf(" %-14s%-14s\n", rowset[i].col1_val, rowset[i].col2_val); } /* output the Row Status Array if the complete rowset was not returned. */ if ( rowsFetchedNb != ROWSET_SIZE) { printf(" Previous rowset was not full:\n"); for (i = 0; i < ROWSET_SIZE; i++) { printf(" Row Status Array[%i] = %s\n", i, ROWSTATVALUE[rowStatus[i]]); } } /* fetch the rowset: row15, row16, row17, row18, row19 */ printf("\n Fetch the rowset: row15, row16, row17, row18, row19.\n"); sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_ABSOLUTE, 15 ); STMT_HANDLE_CHECK( hstmt, sqlrc); /* SQLFetchScroll with SQL_FETCH_LAST */ printf(" SQLFetchScroll with SQL_FETCH_LAST.\n"); printf(" COL1 COL2 \n" ) ; printf(" ------------ -------------\n" ) ; sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_LAST, 0 ); STMT_HANDLE_CHECK( hstmt, sqlrc); if (sqlrc == SQL_NO_DATA_FOUND) { printf("\n Data not found.\n"); } for ( i = 0; i < rowsFetchedNb; i++) { printf(" %-14s%-14s\n", rowset[i].col1_val, rowset[i].col2_val); } /* output the Row Status Array if the complete rowset was not returned. */ if ( rowsFetchedNb != ROWSET_SIZE) { printf(" Previous rowset was not full:\n"); for (i = 0; i < ROWSET_SIZE; i++) { printf(" Row Status Array[%i] = %s\n", i, ROWSTATVALUE[rowStatus[i]]); } } /* fetch the rowset: row15, row16, row17, row18, row19 */ printf("\n Fetch the rowset: row15, row16, row17, row18, row19.\n"); sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_ABSOLUTE, 15 ); STMT_HANDLE_CHECK( hstmt, sqlrc); /* SQLFetchScroll with SQL_FETCH_RELATIVE offset 3 */ printf(" SQLFetchScroll with SQL_FETCH_RELATIVE offset 3.\n"); printf(" COL1 COL2 \n" ) ; printf(" ------------ -------------\n" ) ; sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_RELATIVE, 3 ); STMT_HANDLE_CHECK( hstmt, sqlrc); if (sqlrc == SQL_NO_DATA_FOUND) { printf("\n Data not found.\n"); } for ( i = 0; i < rowsFetchedNb; i++) { printf(" %-14s%-14s\n", rowset[i].col1_val, rowset[i].col2_val); } /* output the Row Status Array if the complete rowset was not returned. */ if ( rowsFetchedNb != ROWSET_SIZE) { printf(" Previous rowset was not full:\n"); for (i = 0; i < ROWSET_SIZE; i++) { printf(" Row Status Array[%i] = %s\n", i, ROWSTATVALUE[rowStatus[i]]); } } /* set the bookmark at the row 17 */ printf("\n Set the bookmark at the row 17.\n"); sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_ABSOLUTE, 15 ); STMT_HANDLE_CHECK( hstmt, sqlrc); /* 1->15, 2->16, 3->17*/ sqlrc = SQLSetPos( hstmt, 3, SQL_POSITION, SQL_LOCK_NO_CHANGE); STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLGetData(hstmt, 0, SQL_C_LONG, bookmark.val, 4, &bookmark.ind); STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLSetStmtAttr( hstmt, SQL_ATTR_FETCH_BOOKMARK_PTR, (SQLPOINTER) bookmark.val, 0); STMT_HANDLE_CHECK( hstmt, sqlrc); /* SQLFetchScroll with SQL_FETCH_BOOKMARK offset 4 */ printf(" SQLFetchScroll with SQL_FETCH_BOOKMARK offset 4.\n"); printf(" COL1 COL2 \n" ) ; printf(" ------------ -------------\n" ) ; sqlrc = SQLFetchScroll( hstmt, SQL_FETCH_BOOKMARK, 4 ); STMT_HANDLE_CHECK( hstmt, sqlrc); if (sqlrc == SQL_NO_DATA_FOUND) { printf("\n Data not found.\n"); } for ( i = 0; i < rowsFetchedNb; i++) { printf(" %-14s%-14s\n", rowset[i].col1_val, rowset[i].col2_val); } /* output the Row Status Array if the complete rowset was not returned. */ if ( rowsFetchedNb != ROWSET_SIZE) { printf(" Previous rowset was not full:\n"); for (i = 0; i < ROWSET_SIZE; i++) { printf(" Row Status Array[%i] = %s\n", i, ROWSTATVALUE[rowStatus[i]]); } } /* free the statement handle */ sqlrc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); /* drop the test table */ printf("\n Drop the test table.\n"); sqlrc = SQLExecDirect( hstmtTable, (SQLCHAR*)"DROP TABLE fetchScrollTable ", SQL_NTS ) ; STMT_HANDLE_CHECK( hstmtTable, sqlrc); /* free the statement handle */ sqlrc = SQLFreeHandle( SQL_HANDLE_STMT, hstmtTable ) ; STMT_HANDLE_CHECK( hstmtTable, sqlrc); return(rc); }