Subject: re: ODBC 3.5 with cygwin B20.1
From: "Toby Popenfoose" <[email-masked]>
To: [email-masked]
Cc: [email-masked], [email-masked], [email-masked], [email-masked], [email-masked]
Date: Wed, 10 Mar 1999 05:37:47 +0000

The best developer's guide I have found is:

ODBC 3.5 Developer's Guide (McGraw-Hill Series) by Roger Sanders

it is quite large, but easy reading and all MS Access examples with ODBC compile
for cygwin right off the CD.  I went through the whole book in a week.

If you do not have the MS ODBC 3.5 DLL's and INCLUDE's yet, the ODBC SDK can be
downloaded from:

www.microsoft.com/data/odbc/download/odbc35in.exe

It is over 3.5Mbytes.  The questions regarding SQLAllocHandle etc. not being
found in the CYGWIN B20.1 release is because that libodbc32.a is from a previous
version of ODBC.  To update libodbc32.a you need the ODBC 3.5 SDK.  After you
have installed it, you can find a odbc32.lib in the lib32 directory of the SDK. 
 You can create a .def file to create your own libodbc32.a to use with the new
DLL by typing the following command line:

nm odbc32.lib | grep "0 T _" | sed s/"00000000 T _"//g > odbc32.def

then edit the def file to insert the following two lines as the first two lines
in the def file.

LIBRARY ODBC32.dll
EXPORTS

Now type the following command line:

dlltool -k -D odbc32.dll -d odbc32.def -l libodbc32.a

Move libodbc32.a to your lib path (you can overwrite the one that came with
cygwin) and you are ready to go.  You can use the same procedure with
odbccp32.dll.

I have used the following odbc code examples with CYGWIN B20.1 and ODBC 3.5
under Windows NT 4.0. It is not completely polished :)
Toby Popenfoose
[email-masked]

# makefile ***********************************************************
.SUFFIXES: .exe .cpp .o

all: sql.exe showSources.exe showDrivers.exe showFunctions.exe testSQL.exe
testExtSQL.exe

sql.exe: sql.o odbcClass.o
 g++ -DWIN32 -I/odbc35/include -o $@ sql.o odbcClass.o -lodbc32
 $@

showSources.exe: showSources.o odbcClass.o
 g++ -DWIN32 -I/odbc35/include -o $@ showSources.o odbcClass.o -lodbc32
 $@

showDrivers.exe: showDrivers.o odbcClass.o
 g++ -DWIN32 -I/odbc35/include -o $@ showDrivers.o odbcClass.o -lodbc32
 $@

showFunctions.exe: showFunctions.o odbcClass.o
 g++ -DWIN32 -I/odbc35/include -o $@ showFunctions.o odbcClass.o -lodbc32
 $@

testSQL.exe: testSQL.o odbcClass.o
 g++ -DWIN32 -I/odbc35/include -o $@ testSQL.o odbcClass.o -lodbc32

testExtSQL.exe: testExtSQL.o odbcClass.o
 g++ -DWIN32 -I/odbc35/include -o $@ testExtSQL.o odbcClass.o -lodbc32

sql.o: odbcClass.h sql.cpp
 g++ -DWIN32 -I/odbc35/include -c -o $@ sql.cpp

showSources.o: odbcClass.h showSources.cpp
 g++ -DWIN32 -I/odbc35/include -c -o $@ showSources.cpp

showDrivers.o: odbcClass.h showDrivers.cpp
 g++ -DWIN32 -I/odbc35/include -c -o $@ showDrivers.cpp

showFunctions.o: odbcClass.h showFunctions.cpp
 g++ -DWIN32 -I/odbc35/include -c -o $@ showFunctions.cpp

testSQL.o: odbcClass.h testSQL.cpp
 g++ -DWIN32 -I/odbc35/include -c -o $@ testSQL.cpp

testExtSQL.o: odbcClass.h testExtSQL.cpp
 g++ -DWIN32 -I/odbc35/include -c -o $@ testExtSQL.cpp

odbcClass.o: odbcClass.h odbcClass.cpp
 g++ -DWIN32 -I/odbc35/include -c -o $@ odbcClass.cpp

//odbcClass.h **********************************************

#define WIN32_LEAN_AND_MEAN
#define STRICT
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include <iostream.h>

int SQLErrorMessages(char *functionName, SQLSMALLINT handleType, SQLHANDLE
handle, SQLRETURN returnValue);

class odbcClass
{
public:
  SQLRETURN returnCode;
  int keepGoing;

  odbcClass();
  virtual ~odbcClass() = 0;
  virtual SQLErrorMessages(char *functionName, SQLSMALLINT handleType, SQLHANDLE
  handle, SQLRETURN returnValue);
};

class odbcEnvironment : public odbcClass
{
public:
  SQLHANDLE hEnvironment;
private:
  static odbcEnvironment* _instance;

protected:
  odbcEnvironment();
public:
  ~odbcEnvironment();
  static odbcEnvironment* Instance();
  void showSources();
  void showDrivers();
  SQLErrorMessages(char *, SQLRETURN);
};

class odbcConnection : public odbcClass
{
public:
  SQLHANDLE hConnection;
  odbcEnvironment *theOdbcEnvironment;

  odbcConnection(char *, char *, char *);
  ~odbcConnection();
  SQLErrorMessages(char *, SQLRETURN);
};

// odbcClass.cpp **********************************************
#include "odbcClass.h"

odbcEnvironment* odbcEnvironment::_instance = 0;

odbcEnvironment::odbcEnvironment()
{
  returnCode = SQL_SUCCESS;

  returnCode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnvironment);
  keepGoing = SQLErrorMessages("odbcEnvironment::SQLAllocHandle", returnCode);
  if (keepGoing)
    {
      /* Set the ODBC version environment attribute */
      returnCode = SQLSetEnvAttr (hEnvironment, SQL_ATTR_ODBC_VERSION,
      (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_UINTEGER); keepGoing = SQLErrorMessages
      ("odbcEnvironment::SQLSetEnvAttr", returnCode);
    }
}

odbcEnvironment::~odbcEnvironment()
{
  //  if (hConnection != NULL)
    returnCode = SQLFreeHandle(SQL_HANDLE_ENV, hEnvironment);
  SQLErrorMessages("odbcEnvironment::SQLFreeHandle", returnCode);
}

odbcEnvironment* odbcEnvironment::Instance()
{
if (_instance == 0)
  _instance = new odbcEnvironment;

return _instance;
}

void odbcEnvironment::showSources()
{
  // Declare The Local Memory Variables
  SQLCHAR      DataSource[31];
  SQLCHAR      Description[255];
  SQLSMALLINT  DS_Size;
  SQLSMALLINT  DescSize;

    // Print The Information Header
  cout.setf(ios::left);
  cout.width(24);
  cout << "Data Source" << "Description (Comment)" << endl;
  for (int i = 0; i < 60; i++)
    cout << "-";
  cout << endl;

  // List All ODBC Data Sources Available
  while (returnCode != SQL_NO_DATA)
    {
      // Retrieve A Data Source Name
      returnCode = SQLDataSources(hEnvironment, SQL_FETCH_NEXT, DataSource,
     sizeof(DataSource), &DS_Size, Description, 
     sizeof(Description), &DescSize);

      // Print The Data Source Name Retrieved
      if (returnCode != SQL_NO_DATA)
        {
   SQLErrorMessages("odbcEnvironment::showSources", returnCode);
   cout.setf(ios::left);
   cout.width(24);
   cout << DataSource << Description << endl;
        }
    }
}

void odbcEnvironment::showDrivers()
{
  // Declare The Local Memory Variables
  SQLCHAR      DriverDesc[255];
  SQLCHAR      Attributes[255];
  SQLSMALLINT  DescSize;
  SQLSMALLINT  AttrSize;
  int          i, j;
  SQLCHAR      Value[50];

    // List All ODBC Data Sources Available
  while (returnCode != SQL_NO_DATA)
    {
      // Retrieve Information About A Driver
      returnCode = SQLDrivers(hEnvironment, SQL_FETCH_NEXT, DriverDesc,
        sizeof(DriverDesc), &DescSize, Attributes, 
        sizeof(Attributes), &AttrSize);

      // Print The Driver Description
      if (returnCode != SQL_NO_DATA)
 {
   SQLErrorMessages("odbcEnvironment::showDrivers", returnCode);
   cout << DriverDesc << endl << endl;

   // Parse And Print The Driver Attributes
   for (i = 0, j = 0; i < AttrSize; i++)
     {
       Value[j] = Attributes[i];
       j++;
       if (Attributes[i] == '\0')
  {
    cout << "  " << Value << endl;
    j = 0;
  }
     }
 }
      cout << endl;
    }
}

odbcEnvironment::SQLErrorMessages(char *functionName, SQLRETURN returnValue) {
  odbcClass::SQLErrorMessages(functionName, SQL_HANDLE_ENV, hEnvironment,
  returnValue);
}

odbcConnection::odbcConnection(char *DSN, char *UID, char *PWD)
{
  returnCode = SQL_SUCCESS;
  theOdbcEnvironment = odbcEnvironment::Instance();
  returnCode = SQLAllocHandle(SQL_HANDLE_DBC, theOdbcEnvironment->hEnvironment,
  &hConnection); keepGoing = SQLErrorMessages("odbcConnection::SQLAllocHandle",
  returnCode); if (keepGoing)
    {
      returnCode = SQLConnect(hConnection, (SQLCHAR *)DSN, SQL_NTS, (SQLCHAR
      *)UID, SQL_NTS, (SQLCHAR *)PWD, SQL_NTS); keepGoing =
      SQLErrorMessages("odbcConnection::SQLConnect", returnCode);
    }
  if (keepGoing)
    {
      returnCode = SQLSetConnectAttr(hConnection, SQL_ATTR_AUTOCOMMIT,
      (SQLPOINTER) SQL_AUTOCOMMIT_OFF, SQL_IS_UINTEGER); keepGoing =
      SQLErrorMessages("odbcConnection::SQLSetConnectAttr", returnCode);
    }
  if (keepGoing)
    {
      returnCode = SQLSetConnectAttr(hConnection, SQL_ATTR_ACCESS_MODE,
      (SQLPOINTER) SQL_MODE_READ_ONLY, SQL_IS_UINTEGER); keepGoing =
      SQLErrorMessages("odbcConnection::SQLSetConnectAttr", returnCode);
    }
}

odbcConnection::~odbcConnection()
{
  returnCode = SQLEndTran(SQL_HANDLE_DBC, hConnection, SQL_ROLLBACK);
  SQLErrorMessages("odbcConnection::SQLEndTran", returnCode);
  returnCode = SQLDisconnect(hConnection);
  SQLErrorMessages("odbcConnection::SQLDisconnect", returnCode);
  returnCode = SQLFreeHandle(SQL_HANDLE_DBC, hConnection);
  SQLErrorMessages("odbcConnection::SQLFreeHandle", returnCode);
}

odbcConnection::SQLErrorMessages(char *functionName, SQLRETURN returnValue) {
  odbcClass::SQLErrorMessages(functionName, SQL_HANDLE_DBC, hConnection,
  returnValue);
}

odbcClass::odbcClass(){}
odbcClass::~odbcClass(){}

int 
odbcClass::SQLErrorMessages (char *functionName, SQLSMALLINT handleType,
SQLHANDLE handle, SQLRETURN returnValue) {
    SQLINTEGER NativeErr;
    SQLCHAR SQLState[6];
    SQLRETURN errorMessageError;
    SQLCHAR ErrMsg[255];
    SQLSMALLINT ErrMsgLen;
    SQLINTEGER recordCount;

    if (returnValue != SQL_SUCCESS)
      {
   cerr << "After " << functionName << " and Return Code : ";
   switch (returnValue)
     {
     case SQL_SUCCESS_WITH_INFO:
  cerr << "SQL SUCCESS WITH INFO";
  break;
     case SQL_NO_DATA:
  cerr << "SQL NO DATA";
  break;
     case SQL_INVALID_HANDLE:
  cerr << "SQL INVALID HANDLE ->> PROGRAMMER MISTAKE <<-";
  break;
     case SQL_NEED_DATA:
  cerr << "SQL NEED DATA";
  break;
     case SQL_STILL_EXECUTING:
  cerr << "SQL STILL EXECUTING";
  break;
     case SQL_ERROR:
  cerr << "SQL ERROR";
  break;
     default:
  cerr << "INVALID RETURN CODE??? ->> PROGRAMMER MISTAKE <<-" << endl;
  return 0;
     }
   cerr << endl;
   if (returnValue != SQL_INVALID_HANDLE)
     {
  if (SQLGetDiagField (handleType, handle, 0, SQL_DIAG_NUMBER,
       &recordCount, SQL_IS_INTEGER, 0) == SQL_SUCCESS)
    {
        for (int i = 1; i <= recordCount; i++)
   {
       errorMessageError = SQLGetDiagRec (handleType, handle, i, SQLState,
       &NativeErr, ErrMsg, 255,
              &ErrMsgLen);
       cerr << "SQLSTATE : " << SQLState << endl;
       cerr << ErrMsg << endl;
   }
    }
     }
      }

    if (returnValue == SQL_SUCCESS || returnValue == SQL_SUCCESS_WITH_INFO)
 return 1;
    else
 return 0;
}

int 
SQLErrorMessages (char *functionName, SQLSMALLINT handleType, SQLHANDLE handle,
SQLRETURN returnValue) {
    SQLINTEGER NativeErr;
    SQLCHAR SQLState[6];
    SQLRETURN errorMessageError;
    SQLCHAR ErrMsg[255];
    SQLSMALLINT ErrMsgLen;
    SQLINTEGER recordCount;

    if (returnValue != SQL_SUCCESS)
      {
   cerr << "After " << functionName << " and Return Code : ";
   switch (returnValue)
     {
     case SQL_SUCCESS_WITH_INFO:
  cerr << "SQL SUCCESS WITH INFO";
  break;
     case SQL_NO_DATA:
  cerr << "SQL NO DATA";
  break;
     case SQL_INVALID_HANDLE:
  cerr << "SQL INVALID HANDLE ->> PROGRAMMER MISTAKE <<-";
  break;
     case SQL_NEED_DATA:
  cerr << "SQL NEED DATA";
  break;
     case SQL_STILL_EXECUTING:
  cerr << "SQL STILL EXECUTING";
  break;
     case SQL_ERROR:
  cerr << "SQL ERROR";
  break;
     default:
  cerr << "INVALID RETURN CODE??? ->> PROGRAMMER MISTAKE <<-" << endl;
  return 0;
     }
   cerr << endl;
   if (returnValue != SQL_INVALID_HANDLE)
     {
  if (SQLGetDiagField (handleType, handle, 0, SQL_DIAG_NUMBER,
       &recordCount, SQL_IS_INTEGER, 0) == SQL_SUCCESS)
    {
        for (int i = 1; i <= recordCount; i++)
   {
       errorMessageError = SQLGetDiagRec (handleType, handle, i, SQLState,
       &NativeErr, ErrMsg, 255,
              &ErrMsgLen);
       cerr << "SQLSTATE : " << SQLState << endl;
       cerr << ErrMsg << endl;
   }
    }
     }
      }

    if (returnValue == SQL_SUCCESS || returnValue == SQL_SUCCESS_WITH_INFO)
 return 1;
    else
 return 0;
}

// showDrivers.cpp ***********************************************

#include "odbcClass.h"

void main(void)
{
  odbcEnvironment *theOdbcEnvironment;
  theOdbcEnvironment = odbcEnvironment::Instance();
  theOdbcEnvironment->showDrivers();
}

// showFunctions.cpp ***********************************************

#include "odbcCLass.h"

int 
main (void)
{
  SQLHDBC hdbc;
  SQLHSTMT hstmt;
  SQLRETURN returnCode;
  SQLSMALLINT sNumResults;
  SQLUSMALLINT supported;
  int keepGoing = 1;
  struct SQLFunctions
  {
    SQLUSMALLINT apiFunctionCode;
    char *apiFunctionName;
  } sqlFunctions[] = {
    { SQL_API_SQLALLOCCONNECT, "SQLALLOCCONNECT << antiquated 2.0 >> " },
    { SQL_API_SQLALLOCENV, "SQLALLOCENV << antiquated 2.0 >> " },
    { SQL_API_SQLALLOCHANDLE, "SQLALLOCHANDLE" },
    { SQL_API_SQLALLOCSTMT, "SQLALLOCSTMT << antiquated 2.0 >> " },
    { SQL_API_SQLBINDCOL, "SQLBINDCOL" },
    { SQL_API_SQLBINDPARAMETER, "SQLBINDPARAMETER" },
    { SQL_API_SQLBROWSECONNECT, "SQLBROWSECONNECT" },
    { SQL_API_SQLBULKOPERATIONS, "SQLBULKOPERATIONS" },
    { SQL_API_SQLCANCEL, "SQLCANCEL" },
    { SQL_API_SQLCLOSECURSOR, "SQLCLOSECURSOR" },
    { SQL_API_SQLCOLATTRIBUTE, "SQLCOLATTRIBUTE" },
    { SQL_API_SQLCOLATTRIBUTES, "SQLCOLATTRIBUTES << antiquated 2.0 >> " }, {
    SQL_API_SQLCOLUMNPRIVILEGES, "SQLCOLUMNPRIVILEGES" }, { SQL_API_SQLCOLUMNS,
    "SQLCOLUMNS" }, { SQL_API_SQLCONNECT, "SQLCONNECT" }, { SQL_API_SQLCOPYDESC,
    "SQLCOPYDESC" }, { SQL_API_SQLDATASOURCES, "SQLDATASOURCES" }, {
    SQL_API_SQLDESCRIBECOL, "SQLDESCRIBECOL" }, { SQL_API_SQLDESCRIBEPARAM,
    "SQLDESCRIBEPARAM" }, { SQL_API_SQLDISCONNECT, "SQLDISCONNECT" }, {
    SQL_API_SQLDRIVERCONNECT, "SQLDRIVERCONNECT" }, { SQL_API_SQLDRIVERS,
    "SQLDRIVERS" }, { SQL_API_SQLENDTRAN, "SQLENDTRAN" }, { SQL_API_SQLERROR,
    "SQLERROR << antiquated 2.0 >> " }, { SQL_API_SQLEXECDIRECT, "SQLEXECDIRECT"
    }, { SQL_API_SQLEXECUTE, "SQLEXECUTE" }, { SQL_API_SQLEXTENDEDFETCH,
    "SQLEXTENDEDFETCH << antiquated 2.0 >> " }, { SQL_API_SQLFETCH, "SQLFETCH"
    }, { SQL_API_SQLFETCHSCROLL, "SQLFETCHSCROLL" }, { SQL_API_SQLFOREIGNKEYS,
    "SQLFOREIGNKEYS" }, { SQL_API_SQLFREECONNECT, "SQLFREECONNECT << antiquated
    2.0 >> " }, { SQL_API_SQLFREEENV, "SQLFREEENV << antiquated 2.0 >> " }, {
    SQL_API_SQLFREEHANDLE, "SQLFREEHANDLE" }, { SQL_API_SQLFREESTMT,
    "SQLFREESTMT" }, { SQL_API_SQLGETCONNECTATTR, "SQLGETCONNECTATTR" }, {
    SQL_API_SQLGETCONNECTOPTION, "SQLGETCONNECTOPTION << antiquated 2.0 >> " },
    { SQL_API_SQLGETCURSORNAME, "SQLGETCURSORNAME" }, { SQL_API_SQLGETDATA,
    "SQLGETDATA" }, { SQL_API_SQLGETDESCFIELD, "SQLGETDESCFIELD" }, {
    SQL_API_SQLGETDESCREC, "SQLGETDESCREC" }, { SQL_API_SQLGETDIAGFIELD,
    "SQLGETDIAGFIELD" }, { SQL_API_SQLGETDIAGREC, "SQLGETDIAGREC" }, {
    SQL_API_SQLGETENVATTR, "SQLGETENVATTR" }, { SQL_API_SQLGETFUNCTIONS,
    "SQLGETFUNCTIONS" }, { SQL_API_SQLGETINFO, "SQLGETINFO" }, {
    SQL_API_SQLGETSTMTATTR, "SQLGETSTMTATTR" }, { SQL_API_SQLGETSTMTOPTION,
    "SQLGETSTMTOPTION << antiquated 2.0 >> " }, { SQL_API_SQLGETTYPEINFO,
    "SQLGETTYPEINFO" }, { SQL_API_SQLMORERESULTS, "SQLMORERESULTS" }, {
    SQL_API_SQLNATIVESQL, "SQLNATIVESQL" }, { SQL_API_SQLNUMPARAMS,
    "SQLNUMPARAMS" }, { SQL_API_SQLNUMRESULTCOLS, "SQLNUMRESULTCOLS" }, {
    SQL_API_SQLPARAMDATA, "SQLPARAMDATA" }, { SQL_API_SQLPARAMOPTIONS,
    "SQLPARAMOPTIONS << antiquated 2.0 >> " }, { SQL_API_SQLPREPARE,
    "SQLPREPARE" }, { SQL_API_SQLPRIMARYKEYS, "SQLPRIMARYKEYS" }, {
    SQL_API_SQLPROCEDURECOLUMNS, "SQLPROCEDURECOLUMNS" }, {
    SQL_API_SQLPROCEDURES, "SQLPROCEDURES" }, { SQL_API_SQLPUTDATA, "SQLPUTDATA"
    }, { SQL_API_SQLROWCOUNT, "SQLROWCOUNT" }, { SQL_API_SQLSETCONNECTATTR,
    "SQLSETCONNECTATTR" }, { SQL_API_SQLSETCONNECTOPTION, "SQLSETCONNECTOPTION
    << antiquated 2.0 >> " }, { SQL_API_SQLSETCURSORNAME, "SQLSETCURSORNAME" },
    { SQL_API_SQLSETDESCFIELD, "SQLSETDESCFIELD" }, { SQL_API_SQLSETDESCREC,
    "SQLSETDESCREC" }, { SQL_API_SQLSETENVATTR, "SQLSETENVATTR" }, {
    SQL_API_SQLSETPARAM, "SQLSETPARAM << antiquated 2.0 >> " }, {
    SQL_API_SQLSETPOS, "SQLSETPOS" }, { SQL_API_SQLSETSCROLLOPTIONS,
    "SQLSETSCROLLOPTIONS << antiquated 2.0 >> " }, { SQL_API_SQLSETSTMTATTR,
    "SQLSETSTMTATTR" }, { SQL_API_SQLSETSTMTOPTION, "SQLSETSTMTOPTION <<
    antiquated 2.0 >> " }, { SQL_API_SQLSPECIALCOLUMNS, "SQLSPECIALCOLUMNS" }, {
    SQL_API_SQLSTATISTICS, "SQLSTATISTICS" }, { SQL_API_SQLTABLEPRIVILEGES,
    "SQLTABLEPRIVILEGES" }, { SQL_API_SQLTABLES, "SQLTABLES" }, {
    SQL_API_SQLTRANSACT, "SQLSQLTRANSACT << antiquated 2.0 >> " }, {
    SQL_API_ALL_FUNCTIONS, "ALL_FUNCTIONS << antiquated 2.0 >> " },   // returns
    bitmap. (not tested) { SQL_API_ODBC3_ALL_FUNCTIONS, "ODBC3_ALL_FUNCTIONS" } 
                // ditto... (maybe in future)
  };

  /* Connect to data source */
  odbcConnection testCon("Northwind","","");
  if (testCon.keepGoing)
    {
      for (int i = 0; i < 76; i++)
 {
returnCode = SQLGetFunctions(testCon.hConnection,
sqlFunctions[i].apiFunctionCode, &supported);
      keepGoing = SQLErrorMessages ("SQLGetFunctions", SQL_HANDLE_DBC,
      testCon.hConnection, returnCode); if (keepGoing)
 {
   cout << sqlFunctions[i].apiFunctionName << "() is ";
   if (supported == TRUE)
     cout << "supported ";
   else
     cout << "not supported ";
   cout << "by the current data source." << endl;
 }
 }
    }
  return 0;
}

// showSources.cpp ***********************************************

#include "odbcClass.h"

void main(void)
{
  odbcEnvironment *theOdbcEnvironment;
  theOdbcEnvironment = odbcEnvironment::Instance();
  theOdbcEnvironment->showSources();
}

// sql.cpp ***********************************************

#include "odbcCLass.h"

int 
main (void)
{
  SQLHDBC hdbc;
  SQLHSTMT hstmt;
  SQLRETURN retcode;
  SQLSMALLINT sNumResults;
  int keepGoing = 1;

  /* Connect to data source */
  odbcConnection testCon("WAR","tp","t13");
  odbcConnection testCon22("Northwind","","");
  if (testCon.keepGoing)
    {
      /* Allocate statement handle */
      retcode = SQLAllocHandle (SQL_HANDLE_STMT, hdbc, &hstmt);
      keepGoing = SQLErrorMessages ("SQLAllocHandle", SQL_HANDLE_STMT, hstmt,
      retcode); if (keepGoing)
 {
   /* Process data */
   retcode = SQLExecDirect (hstmt, (unsigned char *) "SELECT * FROM LDACH00 "
       "WHERE DWORK > '19980814' ", SQL_NTS);
   keepGoing = SQLErrorMessages ("SQLExecDirect", SQL_HANDLE_STMT, hstmt,
   retcode); if (keepGoing)
     {
       retcode = SQLNumResultCols (hstmt, &sNumResults);
       keepGoing = SQLErrorMessages ("SQLNumResultCols", SQL_HANDLE_STMT, hstmt,
       retcode); if (keepGoing)
  {
    if (sNumResults > 0)
      {
        cout << "7" << " = " << sNumResults << endl;
#define NameBufferLength 256
        ULONG dept, costc, dwork, mchrs;
        SQLINTEGER cbdeptID, cbcostcID, cbdworkID, cbmchrsID;
        SQLCHAR nameBuffer[NameBufferLength];
        SQLSMALLINT nameLength, dataType, decimalDigits, nullable;
        SQLUINTEGER columnSize;

        for (SQLSMALLINT i = 1; i <= sNumResults; i++)
   {
     SQLDescribeCol (hstmt, i, nameBuffer, NameBufferLength,
       &nameLength, &dataType, &columnSize, &decimalDigits, &nullable);
     if (dataType == SQL_CHAR)
       {
         cout << nameBuffer << " = " << dataType << ','
       << columnSize << ',' << nameLength
       << ',' << decimalDigits << endl;
       }
     else
       cout << nameBuffer << " = " << dataType << endl;
   }
        SQLBindCol (hstmt, 3, SQL_C_ULONG, &dept, 0, &cbdeptID);
        SQLBindCol (hstmt, 4, SQL_C_ULONG, &costc, 0, &cbcostcID);
        SQLBindCol (hstmt, 7, SQL_C_ULONG, &dwork, 0, &cbdworkID);
        SQLBindCol (hstmt, 24, SQL_C_ULONG, &mchrs, 0, &cbmchrsID);

        while (TRUE)
   {
     retcode = SQLFetch (hstmt);
     if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
       cout << dept << ", " << costc << ", " << dwork << ", " << mchrs << endl;
     else
       break;
   }
      }
  }
     }
   SQLCloseCursor (hstmt);
 }
      SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
    }
  return 0;

}

// testSQL.cpp ***********************************************

#include "odbcCLass.h"

int 
main (void)
{
  SQLHSTMT hstmt;
  SQLRETURN retcode;
  SQLSMALLINT sNumResults;
  int keepGoing = 1;

  /* Connect to data source */
  odbcConnection testCon("Northwind","","");
  if (testCon.keepGoing)
    {
      /* Allocate statement handle */
      retcode = SQLAllocHandle (SQL_HANDLE_STMT, testCon.hConnection, &hstmt);
      keepGoing = SQLErrorMessages ("SQLAllocHandle", SQL_HANDLE_STMT, hstmt,
      retcode); if (keepGoing)
 {
   char sqlBuffer[255];
   cin.getline(sqlBuffer,255);
   cout << sqlBuffer << endl << endl;
   /* Process data */
   retcode = SQLExecDirect (hstmt, (unsigned char *) sqlBuffer, SQL_NTS);
   keepGoing = SQLErrorMessages ("SQLExecDirect", SQL_HANDLE_STMT, hstmt,
   retcode); if (keepGoing)
     {
       retcode = SQLNumResultCols (hstmt, &sNumResults);
       keepGoing = SQLErrorMessages ("SQLNumResultCols", SQL_HANDLE_STMT, hstmt,
       retcode); if (keepGoing && sNumResults > 0)
  {
#define NameBufferLength 255
    SQLCHAR nameBuffer[NameBufferLength];
    SQLSMALLINT nameLength, dataType, decimalDigits, nullable;
    SQLUINTEGER columnSize;
    char *dataArray = new char[NameBufferLength * sNumResults];
    for (SQLSMALLINT i = 1; i <= sNumResults; i++)
      {
        retcode = SQLDescribeCol (hstmt, i, nameBuffer, NameBufferLength,
      &nameLength, &dataType, &columnSize, &decimalDigits, &nullable);
        keepGoing = SQLErrorMessages ("SQLDescribeCol", SQL_HANDLE_STMT, hstmt,
        retcode); if (keepGoing)
   {
     cout << nameBuffer << " , " ;
     retcode = SQLBindCol (hstmt, i, SQL_C_CHAR,
     dataArray+((i-1)*NameBufferLength),
      NameBufferLength, 0);
     SQLErrorMessages ("SQLBindCol", SQL_HANDLE_STMT, hstmt, retcode);
   }
      }
    cout << endl;

    while (TRUE)
      {
        retcode = SQLFetch (hstmt);
        keepGoing = SQLErrorMessages ("SQLFetch", SQL_HANDLE_STMT, hstmt,
        retcode); if (keepGoing)
   {
     for (SQLSMALLINT i = 1; i <= sNumResults; i++)
       {
         cout << dataArray+((i-1)*NameBufferLength) << " , " ;
       }
     cout << endl;
   }
        else
   break;
      }
    delete dataArray;
  }
     }
   SQLCloseCursor (hstmt);
 }
      SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
    }
  return 0;
}

// testExtSQL.cpp ***********************************************

#include "odbcCLass.h"

int 
main (void)
{
  SQLHSTMT hstmt;
  SQLRETURN retcode;
  SQLSMALLINT sNumResults;
  int keepGoing = 1;

  /* Connect to data source */
  odbcConnection testCon("Big1996","","");
  if (testCon.keepGoing)
    {
      /* Allocate statement handle */
      retcode = SQLAllocHandle (SQL_HANDLE_STMT, testCon.hConnection, &hstmt);
      keepGoing = SQLErrorMessages ("SQLAllocHandle", SQL_HANDLE_STMT, hstmt,
      retcode); if (keepGoing)
 {
   //	  char sqlBuffer[255];
   //cin.getline(sqlBuffer,255);
   //cout << sqlBuffer << endl << endl;
   /* Process data */
   retcode = SQLExecDirect (hstmt, 
       (unsigned char *) "select djobyr,ncusto,njob,mjob from ldempl",
       SQL_NTS);
   keepGoing = SQLErrorMessages ("SQLExecDirect", SQL_HANDLE_STMT, hstmt,
   retcode); if (keepGoing)
     {
       retcode = SQLNumResultCols (hstmt, &sNumResults);
       keepGoing = SQLErrorMessages ("SQLNumResultCols", SQL_HANDLE_STMT, hstmt,
       retcode); if (keepGoing && sNumResults > 0)
  {
#define NameBufferLength 255
    SQLCHAR nameBuffer[NameBufferLength];
    SQLSMALLINT nameLength, dataType, decimalDigits, nullable;
    SQLUINTEGER columnSize;
    char *dataArray = new char[NameBufferLength * sNumResults];
    for (SQLSMALLINT i = 1; i <= sNumResults; i++)
      {
        retcode = SQLDescribeCol (hstmt, i, nameBuffer, NameBufferLength,
      &nameLength, &dataType, &columnSize, &decimalDigits, &nullable);
        keepGoing = SQLErrorMessages ("SQLDescribeCol", SQL_HANDLE_STMT, hstmt,
        retcode); if (keepGoing)
   {
     cout << nameBuffer << " , " ;
     retcode = SQLBindCol (hstmt, i, SQL_C_CHAR,
     dataArray+((i-1)*NameBufferLength),
      NameBufferLength, 0);
     SQLErrorMessages ("SQLBindCol", SQL_HANDLE_STMT, hstmt, retcode);
   }
      }
    cout << endl;

    while (TRUE)
      {
        retcode = SQLFetch (hstmt);
        keepGoing = SQLErrorMessages ("SQLFetch", SQL_HANDLE_STMT, hstmt,
        retcode); if (keepGoing)
   {
     for (SQLSMALLINT i = 1; i <= sNumResults; i++)
       {
         cout << dataArray+((i-1)*NameBufferLength) << " , " ;
       }
     cout << endl;
   }
        else
   break;
      }
    delete dataArray;
  }
     }
   SQLCloseCursor (hstmt);
 }
      SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
    }
  return 0;
}

// Toby Popenfoose [email-masked]

--
Want to unsubscribe from this list?
Send a message to [email-masked]