/**********************************************************************
* FILENAME :        ReadingSingleLongTextFields .c
*
* DESCRIPTION :
*		This example retrieves data fram a choice of tables but shows
*               how to read a long text fields (i.e. in the case
*               of TestTBL3 and TestTBL4 which both have a LONGVARCHAR field
*               Memo1).
*
* ODBC USAGE :
*		Prompts for table number to get table name
*               Formats select based on table columns
*		SQLExecDirect to execute SELECT statement
*		SQLFetch to get the next rowset
*		SQLGetData to retrieve the data for non long text fields
*		SQLGetData to return text data for long text field Memo1
*               until SQL_NO_DATA
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <sql.h>
#include <sqlext.h>
#include <string.h>

#include "util.c"

#define TEXTSIZE  12000 // How big the Memo1 field is
#define NAMELEN 30
#define BIRTHDAYLEN 256
#define DATASIZE  520+1 // How much of the Memo1 field to read in one go

#define TRUE 1

int main () {

    SQLHENV  henv  = SQL_NULL_HENV;   // Environment
    SQLHDBC  hdbc  = SQL_NULL_HDBC;   // Connection handle
    SQLHSTMT hstmt = SQL_NULL_HSTMT;  // Statement handle

    SQLRETURN retcode;

    SQLCHAR	name[NAMELEN];
    SQLINTEGER age;
    SQLCHAR birthday[BIRTHDAYLEN];
    SQLCHAR Memo1[DATASIZE];

    SQLLEN  siname, siage, sibirthday, siMemo1;
    SQLLEN	status;
    SQLSMALLINT statuslen;

    // Table and SQL statement
    int tableNo=-1;
    char table[32];
    char sqlstr[100];

    getInt ("Which Table"
             "\n0 (Quit)"
             "\n1 (TestTBL3)"
             "\n2 (TestTBL4)"
             "\n  ?", &tableNo, 'N', 0);
    if (tableNo != 1 && tableNo != 2) {
    	goto exit;
    } else {
    	if (tableNo==1) strcpy (table, "TestTBL3");
    	if (tableNo==2) strcpy (table, "TestTBL4");
    }

    sprintf (sqlstr,
        "SELECT name, age, birthday, Memo1 from %s order by name", table);

    // Allocate the ODBC environment and save handle.
    retcode = SQLAllocHandle (SQL_HANDLE_ENV, NULL, &henv);
    CHECK_ERROR(retcode, "SQLAllocHandle(SQL_HANDLE_ENV)",
                henv, SQL_HANDLE_ENV);

    // Notify ODBC that this is an ODBC 3.0 app.
    retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,
                                            (SQLPOINTER) SQL_OV_ODBC3, 0);
    CHECK_ERROR(retcode, "SQLSetEnvAttr(SQL_ATTR_ODBC_VERSION)",
                henv, SQL_HANDLE_ENV);

    // Allocate ODBC connection handle and connect.
    retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
    CHECK_ERROR(retcode, "SQLAllocHandle(SQL_HANDLE_DBC)",
                hdbc, SQL_HANDLE_DBC);

    retcode=SQLDriverConnect(hdbc, NULL, "DSN=DATASOURCE;",
                            SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE);
    CHECK_ERROR(retcode, "SQLDriverConnect(DATASOURCE)",
                hdbc, SQL_HANDLE_DBC);

    // Allocate statement handle.
    retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
    CHECK_ERROR(retcode, "SQLAllocHandle(SQL_HANDLE_STMT)",
                hstmt, SQL_HANDLE_STMT);

    // Execute the command.
    printf ("Call SQLExecDirect with : %s \n", sqlstr);
    retcode = SQLExecDirect(hstmt, (UCHAR*)sqlstr, SQL_NTS);
    CHECK_ERROR(retcode, "SQLExecDirect()", hstmt, SQL_HANDLE_STMT);

    while (TRUE) {
    	retcode = SQLFetch(hstmt);
    	if (retcode == SQL_ERROR || retcode == SQL_SUCCESS_WITH_INFO) {
    		printf ("Status = %i\n", retcode);
    	}
    	if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO){

    		/* Get data for columns 1, 2, and 3 */
    		memset (name, ' ', NAMELEN);
    		//age=0;
    		memset (birthday, ' ', BIRTHDAYLEN);
    		retcode = SQLGetData(hstmt, 1,
                                 SQL_C_CHAR, name, NAMELEN,
                                 &siname);
    		retcode = SQLGetData(hstmt, 2,
                                 SQL_C_ULONG, &age, 0,
                                 &siage);
    		retcode = SQLGetData(hstmt, 3,
                                 SQL_C_CHAR, birthday, BIRTHDAYLEN,
                                 &sibirthday);
    		printf("%.10s, %i, %.10s\n", name, age, birthday);
    		// read Memo1 field until SQL_NO_DATA
    		do {
    			memset (Memo1, ' ', sizeof (Memo1));
    			retcode = SQLGetData(hstmt, 4, SQL_CHAR,
                                     Memo1, DATASIZE, &siMemo1);

    			// Print the row of data
                if (siMemo1!=-1) {
    				printf("%.75s\n", Memo1);
    			}
    		} while (retcode == SQL_SUCCESS_WITH_INFO &&
                        SQLGetDiagField(SQL_HANDLE_STMT, hstmt, 1, 4,
                                        &status, SQL_INTEGER,
                                        &statuslen)
                        != SQL_NO_DATA);
    	} else {
    		break;
    	}
    }

exit:

    printf ("\nComplete.\n");

    // Clean up.
    if (hstmt != SQL_NULL_HSTMT)
    	SQLFreeHandle(SQL_HANDLE_STMT, hstmt);

    if (hdbc != SQL_NULL_HDBC) {
    	SQLDisconnect(hdbc);
    	SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
    }

    if (henv != SQL_NULL_HENV)
    	SQLFreeHandle(SQL_HANDLE_ENV, henv);

    return 0;
}

Further information