/**********************************************************************
* FILENAME : AsyncExecution.c
*
* DESCRIPTION :
* Example shows use of parameter array but with Asyncronous
* operation on SQLExecDirect()
*
* ODBC USAGE :
* NOTE For SELECT statements, the SQL_PARAM_ARRAY_SELECTS
* option indicates whether a result set is available for
* each set of parameters (SQL_PAS_BATCH) or whether only
* one result set is available (SQL_PAS_NO_BATCH). In the
* case of SQL_PAS_BATCH, the SELECT is split up into a
* number of selects, on per parameter set.
*
* Uses TestTBL1,
*
* PersonID int NOT NULL IDENTITY(1,1),
* FirstName varchar(255) NOT NULL,
* LastName varchar(255),
* Address varchar(255),
* City varchar(255)
*/
#include <stdio.h>
#include <stdlib.h>
#include <sql.h>
#include <sqlext.h>
#include <string.h>
#include "util.c"
#define PARAM_ARRAY_SIZE 30
#define FIRSTNAME_LEN 256
#define LASTNAME_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, AsyncRetCode;
// Select statements to return person details from TestTBL1
SQLCHAR *stmt = "SELECT PersonID, FirstName, LastName, Address, City FROM TestTBL1 WHERE PersonID=?";
// Array of person IDs to get list of all Record IDs for
SQLINTEGER PersonIDs[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
20,21,22,23,24,25,26,27,28,29,30};
// Column binding variables
SQLLEN PersonID;
SQLLEN PersonID_l;
SQLCHAR FirstName [FIRSTNAME_LEN];
SQLLEN FirstName_l;
SQLCHAR LastName [LASTNAME_LEN];
SQLLEN LastName_l;
SQLCHAR Address [ADDRESS_LEN];
SQLLEN Address_l;
SQLCHAR City [CITY_LEN];
SQLLEN City_l;
int i;
SQLUSMALLINT ParamStatusArray[PARAM_ARRAY_SIZE];
SQLLEN ParamsProcessed=0;
// 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_HANDLE_ENV)", 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);
// Connect to DATASOURCE
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);
// Set parameter set size, status array and params processed pointers
retcode = SQLSetStmtAttr (hstmt, SQL_ATTR_PARAMSET_SIZE,
(SQLPOINTER) PARAM_ARRAY_SIZE, 0);
retcode = SQLSetStmtAttr (hstmt, SQL_ATTR_PARAM_STATUS_PTR,
ParamStatusArray, PARAM_ARRAY_SIZE);
retcode = SQLSetStmtAttr (hstmt, SQL_ATTR_PARAMS_PROCESSED_PTR,
&ParamsProcessed, 0);
// Enable Async Operation - if ASYNC is not allowed, SQLSetStmtAttr
// will return an error
retcode = SQLSetStmtAttr (hstmt, SQL_ATTR_ASYNC_ENABLE,
(SQLPOINTER) SQL_ASYNC_ENABLE_ON, 0);
CHECK_ERROR(retcode, "SQLSetStmtAttr(SQL_ATTR_ASYNC_ENABLE)",
hstmt, SQL_HANDLE_STMT);
// Bind array values of parameter 1
retcode = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG,
SQL_INTEGER, 0, 0, PersonIDs, 0, NULL);
/* Bind columns to the Record_num Field of the first row in the array */
retcode = SQLBindCol(hstmt, 1, SQL_C_LONG, &PersonID, 0,
&PersonID_l);
retcode = SQLBindCol(hstmt, 2, SQL_C_CHAR, FirstName, FIRSTNAME_LEN,
&FirstName_l);
retcode = SQLBindCol(hstmt, 3, SQL_C_CHAR, LastName, LASTNAME_LEN,
&LastName_l);
retcode = SQLBindCol(hstmt, 4, SQL_C_CHAR, Address, ADDRESS_LEN,
&Address_l);
retcode = SQLBindCol(hstmt, 5, SQL_C_CHAR, City, CITY_LEN,
&City_l);
// Execute SELECT whilst status SQL_STILL_EXECUTING
retcode = SQLExecDirect (hstmt, stmt, SQL_NTS);
while (retcode==SQL_STILL_EXECUTING) {
printf ("\nStill executing ...");
printf ("\nSnooze ..");
sleep(1);
printf ("\nAwake ..");
retcode = SQLExecDirect (hstmt, stmt, SQL_NTS);
}
CHECK_ERROR(retcode, "SQLExecDirect(SQL_HANDLE_STMT)", hstmt,
SQL_HANDLE_STMT);
// Use SQLFetch and SQLMoreResults to retrieve the records.
do {
retcode = SQLFetch (hstmt);
if (retcode != SQL_NO_DATA) {
printf ("\n - %i, %.10s %.10s %.10s %.10s",
(int) PersonID, FirstName, LastName, Address, City);
}
// SQLMoreResults decides whether there are any more array params to
// process
} while (SQLMoreResults(hstmt) == SQL_SUCCESS);
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