/**********************************************************************
* FILENAME :        SelectWhereInSelect.c
*
* DESCRIPTION :
*       Simple example to retrieve records using a SELECT statement
*       within a WHERE clause.
*
* ODBC USAGE :
*       SQLExecDirect - to execute SELECT statement with Select statement
*                       within a WHERE clause.
*       SQLBindCol    - to bind data areas to columns
*       SQLFetch      - to fetch records until end
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <sql.h>
#include <sqlext.h>
#include <string.h>

#include "util.c"

#define PERSONID_LEN  2
#define LASTNAME_LEN  256
#define FIRSTNAME_LEN 256
#define ADDRESS_LEN 256
#define CITY_LEN  256

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 strFirstName[LASTNAME_LEN], strLastName[FIRSTNAME_LEN];
    SQLCHAR strAddress[ADDRESS_LEN], strCity[CITY_LEN];
    SQLLEN lenFirstName=0, lenLastName=0, lenAddress=0, lenCity=0;
    SQLLEN cPersonId=0, lenPersonId=0;

    int i=0;

    // Allocate environment handle
    retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
    CHECK_ERROR(retcode, "SQLAllocHandle(SQL_HANDLE_ENV)",
                henv, SQL_HANDLE_ENV);

    // Set the ODBC version environment attribute
    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 connection handle
    retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
    CHECK_ERROR(retcode, "SQLAllocHandle(SQL_HANDLE_DBC)",
                hdbc, SQL_HANDLE_DBC);

    // Set login timeout to 5 seconds
    SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);
    CHECK_ERROR(retcode, "SQLSetConnectAttr(SQL_LOGIN_TIMEOUT)",
                hdbc, SQL_HANDLE_DBC);

    // Connect to data source
    retcode = SQLConnect(hdbc, (SQLCHAR*) "DATASOURCE", SQL_NTS,
                         (SQLCHAR*) NULL, 0, NULL, 0);
    CHECK_ERROR(retcode, "SQLConnect(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);

    retcode = SQLExecDirect(hstmt,
                            (SQLCHAR*) "SELECT PersonID, FirstName, LastName, "
                            "Address, City FROM TestTBL1 WHERE FirstName IN "
                            "(SELECT FirstName from TestTBL1Copy)", SQL_NTS);
    CHECK_ERROR(retcode, "SQLExecDirect()", hstmt, SQL_HANDLE_STMT);

    // Bind columns 1, 2, 3, 4 and 5
    retcode = SQLBindCol(hstmt, 1, SQL_C_USHORT, &cPersonId, 2,
                         (SQLPOINTER) &lenPersonId);
    retcode = SQLBindCol(hstmt, 2, SQL_C_CHAR, &strFirstName,
                         FIRSTNAME_LEN, &lenFirstName);
    retcode = SQLBindCol(hstmt, 3, SQL_C_CHAR, &strLastName,
                         LASTNAME_LEN, &lenLastName);
    retcode = SQLBindCol(hstmt, 4, SQL_C_CHAR, &strAddress,
                         ADDRESS_LEN, &lenAddress);
    retcode = SQLBindCol(hstmt, 5, SQL_C_CHAR, &strCity,
                         CITY_LEN, &lenCity);

    // Fetch and print each row of data until SQL_NO_DATA returned.
    for (i=0; ; i++) {
        retcode = SQLFetch(hstmt);
        if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
            printf("Record %d: %i %s, %s, %s, %s\n", i+1, (int) cPersonId,
                   rtrim(strFirstName, ' '), rtrim(strLastName, ' '),
                   rtrim(strAddress, ' '), rtrim(strCity, ' '));
        } else {
            if (retcode != SQL_NO_DATA) {
                CHECK_ERROR(retcode, "SQLFetch()", hstmt, SQL_HANDLE_STMT);
            } else {
                break;
            }
        }
    }

exit:

    printf ("\nComplete.\n");

    // Free handles
    // Statement
    if (hstmt != SQL_NULL_HSTMT)
        SQLFreeHandle(SQL_HANDLE_STMT, hstmt);

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

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

    return 0;
}

Further information