/******************************************************************************* ** ** Source File Name = dbuse.c 1.6 ** ** Licensed Materials - Property of IBM ** ** (C) COPYRIGHT International Business Machines Corp. 1995, 1999 ** 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 use a database. ** ** For more information about these samples see the README file. ** ** 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 */ int StmtExecDirect( SQLHANDLE) ; int ConnExecTransact( SQLHANDLE) ; int StmtBindParam( SQLHANDLE) ; int StmtExecute( SQLHANDLE) ; int StmtExecCompound( SQLHANDLE) ; int StmtExecAsync( SQLHANDLE) ; int DescSetGetRec( SQLHANDLE) ; int DescSetGetField( SQLHANDLE ); int DescCopy( 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\nDATABASES: HOW TO USE A DATABASE.\n"); /* initialize the CLI application */ rc = CLIAppInit( dbAlias, user, pswd, &henv, &hdbc, (SQLPOINTER)SQL_AUTOCOMMIT_ON); if ( rc != 0 ) return( rc ) ; /* using SQLExecDirect */ rc = StmtExecDirect( hdbc) ; /* using SQLEndTrans for */ rc = ConnExecTransact( hdbc) ; /* using SQLBindParameter */ rc = StmtBindParam( hdbc) ; /* using SQLExecute */ rc = StmtExecute( hdbc) ; /* using a compound SQL statement */ rc = StmtExecCompound( hdbc) ; /* executing an SQL statement asynchronously */ rc = StmtExecAsync( hdbc) ; /* using descriptors */ rc = DescSetGetRec( hdbc) ; rc = DescSetGetField( hdbc) ; rc = DescCopy( hdbc) ; /* terminate the CLI application */ rc = CLIAppTerm( &henv, &hdbc, dbAlias); return( rc ) ; } /* end main */ /****************************************************************************** ** StmtExecDirect - how to execute an SQL statement directly ******************************************************************************/ int StmtExecDirect( SQLHANDLE hdbc) { SQLRETURN sqlrc = SQL_SUCCESS; int rc = 0; SQLHANDLE hstmt ; /* statement handle */ SQLCHAR * stmt1 = ( SQLCHAR * ) "CREATE TABLE table1(col1 INTEGER)" ; SQLCHAR * stmt2 = ( SQLCHAR * ) "DROP TABLE table1" ; printf("\nUSE THE CLI FUNCTIONS\n"); printf("-SQLSetConnectAttr\n-SQLAllocHandle\n"); printf("-SQLExecDirect\n-SQLFreeHandle\n"); printf("TO EXECUTE SQL STATEMENTS DIRECTLY:\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 statement 1*/ printf("\n Execute directly %s.\n", stmt1); sqlrc = SQLExecDirect( hstmt, stmt1, SQL_NTS ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); /* execute directly statement 2 */ printf(" Execute directly %s.\n", stmt2); sqlrc = SQLExecDirect( hstmt, stmt2, SQL_NTS ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); /* free the statement handle */ sqlrc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); return(rc); } /****************************************************************************** ** ConnExecTransact - how to perform a transaction ** on one connection ******************************************************************************/ int ConnExecTransact( SQLHANDLE hdbc) { SQLRETURN sqlrc = SQL_SUCCESS; int rc = 0; SQLHANDLE hstmt ; /* statement handle */ SQLCHAR * stmt1 = ( SQLCHAR * )"CREATE TABLE table1(col1 INTEGER)" ; SQLCHAR * stmt2 = ( SQLCHAR * )"CREATE TABLE table2(col1 INTEGER)" ; SQLCHAR * stmt3 = ( SQLCHAR * )"DROP TABLE table1" ; SQLCHAR * stmt4 = ( SQLCHAR * )"DROP TABLE table2" ; printf("\nUSE THE CLI FUNCTIONS\n"); printf("-SQLSetConnectAttr\n-SQLAllocHandle\n"); printf("-SQLExecDirect\n-SQLEndTrans\n-SQLFreeHandle\n"); printf("TO PERFORM A TRANSACTION ON ONE CONNECTION:\n"); /* set AUTOCOMMIT OFF */ sqlrc = SQLSetConnectAttr( hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_NTS) ; DBC_HANDLE_CHECK( hdbc, sqlrc); printf("\n Transactions enabled\n"); /* allocate a statement handle */ sqlrc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; DBC_HANDLE_CHECK( hdbc, sqlrc); printf(" Perform a transaction on this connection\n"); /* execute directly statement 1 */ printf(" executing %s...\n", stmt1); sqlrc = SQLExecDirect( hstmt, stmt1, SQL_NTS ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); /* execute directly statement 2 */ printf(" executing %s...\n", stmt2); sqlrc = SQLExecDirect( hstmt, stmt2, SQL_NTS ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); printf(" Commiting the transaction...\n"); sqlrc = SQLEndTran( SQL_HANDLE_DBC, hdbc, SQL_COMMIT ); DBC_HANDLE_CHECK( hdbc, sqlrc); printf( " Transaction commited.\n"); printf(" Perform another transaction on this connection\n"); /* execute directly statement 3 */ printf(" executing %s...\n", stmt3); sqlrc = SQLExecDirect( hstmt, stmt3, SQL_NTS ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); /* execute directly statement 4 */ printf(" executing %s...\n", stmt4); sqlrc = SQLExecDirect( hstmt, stmt4, SQL_NTS ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); printf(" Commiting the transaction...\n"); sqlrc = SQLEndTran( SQL_HANDLE_DBC, hdbc, SQL_COMMIT ); DBC_HANDLE_CHECK( hdbc, sqlrc); printf( " Transaction commited.\n"); /* free the statement handle */ sqlrc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); return(rc); } /****************************************************************************** ** StmtBindParam - how to bind parameteres to an SQL statement ******************************************************************************/ int StmtBindParam( SQLHANDLE hdbc) { SQLRETURN sqlrc = SQL_SUCCESS; int rc = 0; SQLHANDLE hstmt ; /* statement handle */ SQLCHAR * stmt = ( SQLCHAR * ) "DELETE FROM org WHERE deptnumb = ? AND division = ? " ; SQLSMALLINT parameter1 = 0; char parameter2[20]; printf("\nUSE THE CLI FUNCTIONS\n"); printf("-SQLSetConnectAttr\n-SQLAllocHandle\n-SQLBindParameter\n"); printf("-SQLExecDirect\n-SQLEndTrans\n-SQLFreeHandle\n"); printf("TO SHOW HOW TO BIND PARAMETERS TO AN SQL STATEMENT:\n"); /* set AUTOCOMMIT OFF */ sqlrc = SQLSetConnectAttr( hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_NTS) ; DBC_HANDLE_CHECK( hdbc, sqlrc); printf("\n Transactions enabled\n"); /* allocate a statement handle */ sqlrc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; DBC_HANDLE_CHECK( hdbc, sqlrc); /* bind parameter1 and parameter2 to the statement */ printf(" Bind parameter1 and parameter2 to the statement\n"); printf(" %s\n", stmt); sqlrc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_SHORT, SQL_SMALLINT, 0, 0, ¶meter1, 0, NULL); STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 20, 0, parameter2, 20, NULL); STMT_HANDLE_CHECK( hstmt, sqlrc); /* execute the statement for parameter1 = 15 and parameter2 = 'Eastern' */ printf(" Execute the statement for\n"); printf(" parameter1 = 15 and\n"); printf(" parameter2 = 'Eastern'\n"); parameter1 = 15; strcpy(parameter2, "Eastern"); sqlrc = SQLExecDirect( hstmt, stmt, SQL_NTS ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); /* execute the statement for parameter1 = 84 and parameter2 = 'Western' */ printf(" Execute the statement for\n"); printf(" parameter1 = 84 and\n"); printf(" parameter2 = 'Western'\n"); parameter1 = 84; strcpy(parameter2, "Western"); sqlrc = SQLExecDirect( hstmt, stmt, SQL_NTS ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); printf(" Rolling back the transaction...\n"); sqlrc = SQLEndTran( SQL_HANDLE_DBC, hdbc, SQL_ROLLBACK ); DBC_HANDLE_CHECK( hdbc, sqlrc); printf( " Transaction rolled back.\n"); /* free the statement handle */ sqlrc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); return(rc); } /****************************************************************************** ** StmtExecute - how to execute a prepared SQL statement ******************************************************************************/ int StmtExecute( SQLHANDLE hdbc) { SQLRETURN sqlrc = SQL_SUCCESS; int rc = 0; SQLHANDLE hstmt ; /* statement handle */ SQLCHAR * stmt = ( SQLCHAR * ) "DELETE FROM org WHERE deptnumb = ? " ; SQLSMALLINT parameter1 = 0; printf("\nUSE THE CLI FUNCTIONS\n"); printf("-SQLSetConnectAttr\n-SQLAllocHandle\n"); printf("-SQLPrepare\n-SQLBindParameter\n"); printf("-SQLExecute\n-SQLEndTran\n-SQLFreeHandle\n"); printf("TO SHOW HOW TO EXECUTE A PREPARED SQL STATEMENT:\n"); /* set AUTOCOMMIT OFF */ sqlrc = SQLSetConnectAttr( hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_NTS) ; DBC_HANDLE_CHECK( hdbc, sqlrc); printf("\n Transactions enabled\n"); /* allocate a statement handle */ sqlrc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; DBC_HANDLE_CHECK( hdbc, sqlrc); /* prepare the statement */ printf(" Prepare the statement\n"); printf(" %s\n", stmt); sqlrc = SQLPrepare( hstmt, stmt, SQL_NTS ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); /* bind parameter1 to the statement */ printf(" Bind parameter1 to the statement\n"); printf(" %s\n", stmt); sqlrc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_SHORT, SQL_SMALLINT, 0, 0, ¶meter1, 0, NULL); STMT_HANDLE_CHECK( hstmt, sqlrc); /* execute the statement for parameter1 = 15 */ printf(" Execute the prepared statement for\n"); printf(" parameter1 = 15\n"); parameter1 = 15; sqlrc = SQLExecute( hstmt ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); /* execute the statement for parameter1 = 84 */ printf(" Execute the prepared statement for\n"); printf(" parameter1 = 84\n"); parameter1 = 84; sqlrc = SQLExecute( hstmt ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); printf(" Rolling back the transaction...\n"); sqlrc = SQLEndTran( SQL_HANDLE_DBC, hdbc, SQL_ROLLBACK ); DBC_HANDLE_CHECK( hdbc, sqlrc); printf( " Transaction rolled back.\n"); /* free the statement handle */ sqlrc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); return(rc); } /****************************************************************************** ** StmtExecCompound - how to execute a compound SQL statement ******************************************************************************/ int StmtExecCompound( SQLHANDLE hdbc) { SQLRETURN sqlrc = SQL_SUCCESS; int rc = 0; SQLHANDLE hstmt, compnd_hstmt[4] ; /* statement hadles */ SQLCHAR * compnd_stmt[] = { ( SQLCHAR * ) "INSERT INTO awards (id, award) " "SELECT id, 'Sales Merit' from staff " "WHERE job = 'Sales' AND (comm/100 > years)", ( SQLCHAR * ) "INSERT INTO awards (id, award) " "SELECT id, 'Clerk Merit' from staff " "WHERE job = 'Clerk' AND (comm/50 > years)", ( SQLCHAR * ) "INSERT INTO awards (id, award) " "SELECT id, 'Best ' concat job FROM STAFF " "WHERE comm = (SELECT max(comm) FROM staff WHERE job = 'Clerk')", ( SQLCHAR * ) "INSERT INTO awards (id, award) " "SELECT id, 'Best ' concat job FROM STAFF " "WHERE comm = (SELECT max(comm) FROM STAFF WHERE job = 'Sales')", } ; SQLINTEGER i ; printf("\nUSE THE CLI FUNCTIONS\n"); printf("-SQLSetConnectAttr\n-SQLAllocHandle\n"); printf("-SQLExecDirect\n-SQLPrepare\n-SQLExecute\n"); printf("-SQLEndTrans\n-SQLFreeHandle\n"); printf("TO SHOW HOW TO EXECUTE A COMPOUND SQL STATEMENT:\n"); /* set AUTOCOMMIT OFF */ sqlrc = SQLSetConnectAttr( hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_NTS) ; DBC_HANDLE_CHECK( hdbc, sqlrc); printf("\n Transactions enabled\n"); /* allocate a statement handle */ sqlrc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; DBC_HANDLE_CHECK( hdbc, sqlrc); /* crete the table AWARDS */ sqlrc = SQLExecDirect( hstmt, ( SQLCHAR * ) "CREATE TABLE AWARDS (ID INTEGER, AWARD CHAR(12))" , SQL_NTS ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLEndTran( SQL_HANDLE_DBC, hdbc, SQL_COMMIT ); DBC_HANDLE_CHECK( hdbc, sqlrc); /* prepare 4 substatements */ for ( i = 0; i < 4; i++ ) { sqlrc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &compnd_hstmt[i] ) ; DBC_HANDLE_CHECK( hdbc, sqlrc); sqlrc = SQLPrepare( compnd_hstmt[i], compnd_stmt[i], SQL_NTS ) ; STMT_HANDLE_CHECK( compnd_hstmt[i], sqlrc) ; } /* begin the COMPOUND statement */ printf(" Execute directly:\n"); printf(" BEGIN COMPOUND NOT ATOMIC STATIC\n"); sqlrc = SQLExecDirect( hstmt, ( SQLCHAR * ) "BEGIN COMPOUND NOT ATOMIC STATIC", SQL_NTS ); STMT_HANDLE_CHECK( hstmt, sqlrc ) ; /* execute 4 sub-statements */ for ( i = 0; i < 4; i++ ) { printf(" Execute the sub-statement nb. %d\n", i+1); printf(" of the COMPOUND statement\n" ); sqlrc = SQLExecute( compnd_hstmt[i] ) ; STMT_HANDLE_CHECK( compnd_hstmt[i], sqlrc) ; } /* end the COMPOUND statement */ printf(" Execute directly:\n END COMPOUND COMMIT\n" ); sqlrc = SQLExecDirect( hstmt, ( SQLCHAR * ) "END COMPOUND COMMIT", SQL_NTS ) ; STMT_HANDLE_CHECK( hstmt, sqlrc ) ; /* free the statement handles */ for ( i = 0; i < 4; i++ ) { sqlrc = SQLFreeHandle( SQL_HANDLE_STMT, compnd_hstmt[i]) ; STMT_HANDLE_CHECK( compnd_hstmt[i], sqlrc) ; } /* drop the table AWARDS */ sqlrc = SQLExecDirect( hstmt, ( SQLCHAR * ) "DROP TABLE AWARDS" , SQL_NTS ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLEndTran( SQL_HANDLE_DBC, hdbc, SQL_COMMIT ); DBC_HANDLE_CHECK( hdbc, sqlrc); /* free the statement handle */ sqlrc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); return(rc); } /****************************************************************************** ** StmtExecAsync - how to execute an SQL statement asynchronously ******************************************************************************/ int StmtExecAsync( SQLHANDLE hdbc) { SQLRETURN sqlrc = SQL_SUCCESS; int rc = 0; SQLHANDLE hstmt ; /* statement handle */ SQLCHAR * stmt = ( SQLCHAR * ) "CREATE TABLE table1 ( col1 INTEGER) " ; SQLINTEGER i; SQLSMALLINT outlen; /* For calls to SQLGetInfo() */ SQLUINTEGER uAsyncMode ; /* For calls to SQLGetInfo() */ /* Make the result from SQLGetInfo() more meaningful by mapping */ /* the returned value to the string. */ static char STR_ASYNCMODE[][19] = { "SQL_AM_NONE", "SQL_AM_CONNECTION", "SQL_AM_STATEMENT" }; printf("\nUSE THE CLI FUNCTIONS\n"); printf("-SQLSetConnectAttr\n-SQLAllocHandle\n"); printf("-SQLGetInfo\n-SQLSetStmtAttr\n"); printf("-SQLExecDirect\n-SQLEndTrans\n-SQLFreeHandle\n"); printf("TO SHOW HOW TO EXECUTE AN SQL STATEMENT ASYNCHRONOUSLY:\n"); /* set AUTOCOMMIT OFF */ sqlrc = SQLSetConnectAttr( hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_NTS) ; DBC_HANDLE_CHECK( hdbc, sqlrc); printf("\n Transactions enabled\n"); /* allocate a statement handle */ sqlrc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; DBC_HANDLE_CHECK( hdbc, sqlrc); /* See what type of Asynchronous support is available, * and whether or not the CLI/ODBC configuration keyword ASYNCENABLE * is set on or off. */ sqlrc = SQLGetInfo( hdbc, /* Connection handle */ SQL_ASYNC_MODE, /* Query the support available */ &uAsyncMode, /* Store the result in this variable */ 4, &outlen); STMT_HANDLE_CHECK( hstmt, sqlrc); printf(" SQL_ASYNC_MODE value from SQLGetInfo() is\n"); printf(" %s\n", STR_ASYNCMODE[uAsyncMode]); if ( uAsyncMode == SQL_AM_NONE ) { /* Async not supported */ printf(" Asynchronous execution is not supported \n"); printf(" by this datasource or has been turned off\n"); printf(" by the CLI/ODBC configuration keyword ASYNCENABLE.\n"); printf(" The application will continue,\n"); printf(" but SQLExecDirect()will not be run asynchronously.\n"); } else { printf(" Set asynchronous execution ON at statement level\n"); sqlrc = SQLSetStmtAttr( hstmt, SQL_ATTR_ASYNC_ENABLE, (SQLPOINTER) SQL_ASYNC_ENABLE_ON, 0); STMT_HANDLE_CHECK( hstmt, sqlrc); } /* The while loop is new for the asynchronous sample, the */ /* SQLExecDirect() call remains the same. */ printf(" Call SQLExecDirect\n"); sqlrc = SQLExecDirect(hstmt, stmt, SQL_NTS) ; STMT_HANDLE_CHECK( hstmt, sqlrc); i = 0; while ( sqlrc == SQL_STILL_EXECUTING) { i = i+1 ; if ( i == 400 ) { printf(" ..SQLExecDirect() still executing asynchronously..\n"); /* reset i */ i = 0; } /* Other processing can be performed here, between each call * to see if SQLExecDirect() has finished running asynchronously. * This section will never run if CLI runs the function * synchronously. */ sqlrc = SQLExecDirect(hstmt, stmt, SQL_NTS) ; STMT_HANDLE_CHECK( hstmt, sqlrc); } printf(" Rolling back the transaction...\n"); sqlrc = SQLEndTran( SQL_HANDLE_DBC, hdbc, SQL_ROLLBACK ); DBC_HANDLE_CHECK( hdbc, sqlrc); printf( " Transaction rolled back.\n"); /* free the statement handle */ sqlrc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); return(rc); } /****************************************************************************** ** DescSetGetRec - Show how to use SQLGetDescRec and SQLSetDescRec ******************************************************************************/ int DescSetGetRec( SQLHANDLE hdbc) { SQLRETURN sqlrc = SQL_SUCCESS; SQLRETURN rc = 0; SQLHANDLE hstmt, hstmt1; /* Statement handle */ SQLHANDLE hIRD,hARD; /* Descriptor handle */ SQLINTEGER indicator; SQLSMALLINT i; SQLCHAR colname[20]; SQLSMALLINT namelen; SQLSMALLINT type; SQLSMALLINT subtype; SQLINTEGER width,length,datalen,nameleng; SQLSMALLINT precision, scale, nullable; SQLSMALLINT num_cols; SQLSMALLINT id_no; SQLCHAR thename[20]; struct sqlca sqlca; char sp5[]=" ",sp8[]=" "; SQLCHAR * stmt = (SQLCHAR *) "SELECT id,name FROM staff where dept = 10 "; SQLCHAR * stmt1 = (SQLCHAR *) "SELECT id,name FROM staff where dept = 10 "; printf("\nUSE THE CLI FUNCTIONS \n"); printf("-SQLGetDescRec\n-SQLSetDescRec"); printf("\nOther CLI FUNCTIONS\n"); printf("-SQLSetConnectAttr\n-SQLAllocHandle\n"); printf("-SQLGetStmtAttr\n"); printf("-SQLPrepare\n-SQLBindParameter\n"); printf("-SQLExecute\n-SQLBindCol\n"); printf("-SQLFetch\n-SQLFreeHandle\n"); printf("TO USE DESCRIPTORS:\n"); /* set AUTOCOMMIT on */ rc = SQLSetConnectAttr( hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_NTS) ; DBC_HANDLE_CHECK( hdbc, rc); /* allocate a statement handle */ rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; DBC_HANDLE_CHECK( hdbc, rc); rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt1 ) ; DBC_HANDLE_CHECK( hdbc, rc); printf("%sPrepare the statement\n",sp5); printf("%s%s\n",sp8, stmt); rc = SQLPrepare( hstmt, stmt, SQL_NTS ) ; STMT_HANDLE_CHECK( hstmt, rc); rc = SQLExecute( hstmt ) ; STMT_HANDLE_CHECK( hstmt, rc); /* get implicit row descriptor handle */ rc = SQLGetStmtAttr ( hstmt, SQL_ATTR_IMP_ROW_DESC, &hIRD, SQL_IS_INTEGER, &indicator); STMT_HANDLE_CHECK( hstmt, rc); /* try to get each column information in the resultset */ rc = SQLNumResultCols( hstmt, &num_cols ) ; STMT_HANDLE_CHECK( hstmt, rc); printf("\n%sRecord field/Column information within descriptor: \n",sp5 ); for(i=1; i<= num_cols; i++){ rc = SQLGetDescRec(hIRD, i, colname, sizeof(colname), &namelen, &type, &subtype, &width, &precision, &scale, &nullable); if (rc == SQL_SUCCESS) { printf("%sColumn = %d: \n",sp5,i ); printf("%sName = %s \n", sp8,colname ); printf("%sData type = %d \n", sp8,type ); printf("%sSub type = %d \n", sp8,subtype ); printf("%sWidth = %d \n", sp8,width ); printf("%sPrecision = %d \n", sp8,precision ); printf("%sScale = %d \n", sp8,scale ); printf("%sNullable = %d \n", sp8,nullable ); } STMT_HANDLE_CHECK( hstmt, rc); } rc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; STMT_HANDLE_CHECK( hstmt, rc); strcpy((char*)colname,"Yes"); type=0;subtype=0;width=0;precision=0; scale=0;nullable=0; rc = SQLPrepare( hstmt1, stmt1, SQL_NTS ) ; STMT_HANDLE_CHECK( hstmt1, rc); /* get implicit descriptor handle */ rc = SQLGetStmtAttr ( hstmt1, SQL_ATTR_APP_ROW_DESC, &hARD, 0, NULL); STMT_HANDLE_CHECK( hstmt1, rc); /* Set record/column values via descriptor */ type = SQL_SMALLINT; length = 2; rc = SQLSetDescRec(hARD, 1, type, 0, length, 0, 0, &id_no, &datalen, NULL); STMT_HANDLE_CHECK( hstmt1, rc); type = SQL_CHAR; length = 20; rc = SQLSetDescRec(hARD, 2, type, 0, length, 0, 0, thename, &nameleng, NULL); STMT_HANDLE_CHECK( hstmt1, rc); printf("\n%sAfter setting record: \n",sp5 ); rc = SQLExecute( hstmt1 ) ; STMT_HANDLE_CHECK( hstmt1, rc); /* Get the record/column value after setting */ for(i=1; i<= num_cols; i++){ rc = SQLGetDescRec(hARD, i, colname, sizeof(colname), &namelen, &type, &subtype, &width, &precision, &scale, &nullable); STMT_HANDLE_CHECK( hstmt1, rc); if (rc == SQL_SUCCESS) { printf("%sColumn = %d: \n",sp5,i ); printf("%sName = %s \n", sp8,colname ); printf("%sData type = %d \n", sp8,type ); printf("%sSub type = %d \n", sp8,subtype ); printf("%sWidth = %d \n", sp8,width ); printf("%sPrecision = %d \n", sp8,precision ); printf("%sScale = %d \n", sp8,scale ); printf("%sNullable = %d \n", sp8,nullable ); } } /* get the result set and print it without using bindcol */ rc = SQLFetch( hstmt1 ); STMT_HANDLE_CHECK( hstmt1, rc); if (rc == SQL_SUCCESS){ printf("%sResultset after using SetDescRec \n",sp5); printf("%s-ID-,---NAME---- \n",sp8); } while ( rc == SQL_SUCCESS){ printf("%s%d %s \n",sp8,id_no,thename); rc = SQLFetch( hstmt1 ); } STMT_HANDLE_CHECK( hstmt1, rc); /* free the statement handle */ rc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt1 ) ; STMT_HANDLE_CHECK( hstmt1, rc); return(rc); } /****************************************************************************** ** DescCopy - Show how to use SQLCopyDesc ******************************************************************************/ int DescCopy( SQLHANDLE hdbc) { SQLRETURN sqlrc = SQL_SUCCESS; SQLRETURN rc = 0; SQLHANDLE hstmt, hstmt1; /* Statement handle */ SQLHANDLE hIRD,hARD; /* Descriptor handle */ SQLINTEGER indicator; SQLSMALLINT i; SQLCHAR colname[20]; SQLSMALLINT namelen; SQLSMALLINT type; SQLSMALLINT subtype; SQLINTEGER width,length,datalen,nameleng; SQLSMALLINT precision, scale, nullable; SQLSMALLINT num_cols; SQLSMALLINT id_no; SQLCHAR thename[20]; struct sqlca sqlca; char sp5[]=" ",sp8[]=" "; SQLCHAR * stmt = (SQLCHAR *)"SELECT id,name FROM staff where dept = 20"; printf("\nUSE THE CLI FUNCTIONS \n"); printf("-SQLCopyDesc"); printf("\nOther CLI FUNCTIONS\n"); printf("-SQLSetConnectAttr\n-SQLAllocHandle\n"); printf("-SQLGetStmtAttr\n"); printf("-SQLPrepare\n-SQLExecute\n"); printf("-SQLGetDescRec\n-SQLSetDescRec\n"); printf("-SQLFetch\n-SQLFreeHandle\n"); printf("TO USE DESCRIPTORS:\n"); /* set AUTOCOMMIT on */ rc = SQLSetConnectAttr( hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_NTS) ; DBC_HANDLE_CHECK( hdbc, rc); /* allocate a statement handle */ rc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ) ; DBC_HANDLE_CHECK( hdbc, rc); printf("%sPrepare the statement\n",sp5); printf("%s%s\n",sp8, stmt); rc = SQLPrepare( hstmt, stmt, SQL_NTS ) ; STMT_HANDLE_CHECK( hstmt, rc); /* get implicit row descriptor handle */ rc = SQLGetStmtAttr ( hstmt, SQL_ATTR_IMP_ROW_DESC, &hIRD, SQL_IS_INTEGER, &indicator); STMT_HANDLE_CHECK( hstmt, rc); /* to get each column information in the resultset */ rc = SQLExecute( hstmt ) ; STMT_HANDLE_CHECK( hstmt, rc); rc = SQLNumResultCols( hstmt, &num_cols ) ; STMT_HANDLE_CHECK( hstmt, rc); printf("\n%sRecord field/Column information before copying descriptor: \n",sp5 ); for(i=1; i<= num_cols; i++){ rc = SQLGetDescRec(hIRD, i, colname, sizeof(colname), &namelen, &type, &subtype, &width, &precision, &scale, &nullable); if (rc == SQL_SUCCESS) { printf("%sColumn = %d: \n",sp5,i ); printf("%sName = %s \n", sp8,colname ); printf("%sData type = %d \n", sp8,type ); printf("%sSub type = %d \n", sp8,subtype ); printf("%sWidth = %d \n", sp8,width ); printf("%sPrecision = %d \n", sp8,precision ); printf("%sScale = %d \n", sp8,scale ); printf("%sNullable = %d \n", sp8,nullable ); } STMT_HANDLE_CHECK( hstmt, rc); } hstmt1=hstmt; strcpy((char*)colname,"Yes"); type=0;subtype=0;width=0;precision=0; scale=0;nullable=0; /* create explicit descriptor handle */ rc = SQLAllocHandle( SQL_HANDLE_DESC, hdbc, &hARD ) ; DBC_HANDLE_CHECK( hdbc, rc); /* copy descriptor */ rc = SQLCopyDesc(hIRD,hARD); STMT_HANDLE_CHECK( hstmt1, rc); rc = SQLSetStmtAttr(hstmt1, SQL_ATTR_APP_ROW_DESC,(SQLPOINTER)hARD, 0 ); STMT_HANDLE_CHECK( hstmt1, rc); /* Set record/column values via descriptor */ type = SQL_SMALLINT; length = 2; rc = SQLSetDescRec(hARD, 1, type, 0, length, 0, 0, &id_no, &datalen, NULL); STMT_HANDLE_CHECK( hstmt1, rc); type = SQL_CHAR; length = 15; rc = SQLSetDescRec(hARD, 2, type, 0, length, 0, 0, thename, &nameleng, NULL); STMT_HANDLE_CHECK( hstmt1, rc); printf("\n%sRecord field/Column information after copying descriptor: \n",sp5 ); /* Get the record/column value after setting */ for(i=1; i<= num_cols; i++){ rc = SQLGetDescRec(hARD, i, colname, sizeof(colname), &namelen, &type, &subtype, &width, &precision, &scale, &nullable); STMT_HANDLE_CHECK( hstmt1, rc); if (rc == SQL_SUCCESS) { printf("%sColumn = %d: \n",sp5,i ); printf("%sData type = %d \n", sp8,type ); printf("%sSub type = %d \n", sp8,subtype ); printf("%sWidth = %d \n", sp8,width ); printf("%sPrecision = %d \n", sp8,precision ); printf("%sScale = %d \n", sp8,scale ); printf("%sNullable = %d \n", sp8,nullable ); } } /* get the result set and print it without using bindcol */ rc = SQLFetch( hstmt1 ); STMT_HANDLE_CHECK( hstmt1, rc); if (rc == SQL_SUCCESS){ printf("%sResultset after using copy descriptor \n",sp5); printf("%s-ID-,---NAME---- \n",sp8); } while ( rc == SQL_SUCCESS){ printf("%s%4d %s \n",sp8,id_no,thename); rc = SQLFetch( hstmt1 ); } STMT_HANDLE_CHECK( hstmt1, rc); /* free the statement handle */ rc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; STMT_HANDLE_CHECK( hstmt, rc); return(rc); } /****************************************************************************** ** DescrUse - how to use descriptors ******************************************************************************/ int DescSetGetField( SQLHANDLE hdbc) { SQLRETURN sqlrc = SQL_SUCCESS; SQLRETURN rc = 0; SQLHANDLE hstmt, hstmt1 ; /* statement handle */ SQLHANDLE hIPD, hIRD, hIRD1, hARD; /* descriptor handle */ SQLSMALLINT descFieldAllocType; SQLSMALLINT descFieldParameterType; SQLCHAR * stmt = ( SQLCHAR * ) "SELECT deptnumb, location FROM org WHERE division = ?"; SQLCHAR * stmt1 = ( SQLCHAR * ) "SELECT deptnumb,location FROM org WHERE division = 'Western'"; 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 */ static char ALLOCTYPES[][21] = { "- No 0 Value-", "SQL_DESC_ALLOC_AUTO", "SQL_DESC_ALLOC_USER" }; static char PARAMTYPE[][24] = { "- No 0 Value-", "SQL_PARAM_INPUT", "SQL_PARAM_INPUT_OUTPUT", "- No 3 Value -", "SQL_PARAM_OUTPUT" }; int colCount; SQLCHAR descFieldTypeName[25]; SQLCHAR descFieldLabel[25]; SQLSMALLINT dept_no ; char loc[15] ; char sp5[]=" ",sp8[]=" "; SQLINTEGER indicator; printf("\nUSE THE CLI FUNCTIONS\n"); printf("-SQLGetDescField\n-SQLSetDescField"); printf("\nOther CLI FUNCTIONS\n"); printf("-SQLSetConnectAttr\n-SQLAllocHandle\n"); printf("-SQLGetStmtAttr\n"); printf("-SQLPrepare\n-SQLBindParameter\n"); printf("-SQLExecute\n-SQLBindCol\n"); printf("-SQLFetch\n-SQLFreeHandle\n"); printf("TO USE DESCRIPTORS:\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); sqlrc = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt1 ) ; DBC_HANDLE_CHECK( hdbc, sqlrc); /* get implicit parameter descriptor handle */ sqlrc = SQLGetStmtAttr ( hstmt, SQL_ATTR_IMP_PARAM_DESC, &hIPD, SQL_IS_POINTER, NULL); STMT_HANDLE_CHECK( hstmt, sqlrc); /* see how the header field SQL_DESC_ALLOC_TYPE is set. */ sqlrc = SQLGetDescField( hIPD, 0, /* ignored for header fields */ SQL_DESC_ALLOC_TYPE, &descFieldAllocType, /* The result */ SQL_IS_SMALLINT, NULL ); /* ignored */ STMT_HANDLE_CHECK( hstmt, sqlrc); /* print the descriptor information */ printf("\n The IPD header descriptor field \n"); printf(" SQL_DESC_ALLOC_TYPE is %s\n", ALLOCTYPES[descFieldAllocType]); /* prepare the statement */ printf(" 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); /* see how the field SQL_DESC_PARAMETER_TYPE is set. */ sqlrc = SQLGetDescField( hIPD, 1, /* Look at the parameter */ SQL_DESC_PARAMETER_TYPE, &descFieldParameterType, /* The result */ SQL_IS_SMALLINT, NULL ); /* ignored */ STMT_HANDLE_CHECK( hstmt, sqlrc); /* print the descriptor information */ printf(" The IPD record descriptor field \n"); printf(" SQL_DESC_PARAMETER_TYPE is %s\n", PARAMTYPE[descFieldParameterType]); /* 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); } /* get implicit row descriptor handle */ sqlrc = SQLGetStmtAttr ( hstmt, SQL_ATTR_IMP_ROW_DESC, &hIRD, SQL_IS_POINTER, NULL); STMT_HANDLE_CHECK( hstmt, sqlrc); /* print out some implementation row descriptor fields */ /* from the last SQLFetch() above */ for (colCount = 1; colCount <=2; colCount++) { printf(" Information for column %i\n", colCount); /* see how the descriptor record field SQL_DESC_TYPE_NAME is set */ rc = SQLGetDescField( hIRD, (SQLSMALLINT)colCount, SQL_DESC_TYPE_NAME, /* record field */ descFieldTypeName, /* The result */ 25, NULL ); /* ignored */ STMT_HANDLE_CHECK( hstmt, sqlrc); printf(" IRD record descriptor field \n"); printf(" SQL_DESC_TYPE_NAME is %s\n", descFieldTypeName); /* see how the descriptor record field SQL_DESC_LABEL is set */ rc = SQLGetDescField( hIRD, (SQLSMALLINT)colCount, SQL_DESC_LABEL, /* record field */ descFieldLabel, /* The result */ 25, NULL ); /* ignored */ STMT_HANDLE_CHECK( hstmt, sqlrc); printf(" IRD record descriptor field \n"); printf(" SQL_DESC_LABEL is %s\n", descFieldLabel); } printf("%sPrepare the statement\n",sp5); printf("%s%s\n", sp8,stmt1); sqlrc = SQLPrepare( hstmt1, stmt1, SQL_NTS ) ; STMT_HANDLE_CHECK( hstmt1, sqlrc); /* get implicit row descriptor handle */ sqlrc = SQLGetStmtAttr ( hstmt1, SQL_ATTR_APP_ROW_DESC, &hARD, SQL_IS_INTEGER, &indicator); STMT_HANDLE_CHECK( hstmt1, sqlrc); sqlrc = SQLExecute( hstmt1 ) ; STMT_HANDLE_CHECK( hstmt1, sqlrc); sqlrc = SQLBindCol( hstmt1, 2, SQL_C_CHAR,location.val,15,&indicator); STMT_HANDLE_CHECK( hstmt1, sqlrc); rc = SQLSetDescField( hARD,1, SQL_DESC_TYPE, (SQLPOINTER)SQL_SMALLINT, SQL_IS_SMALLINT); STMT_HANDLE_CHECK( hstmt1, rc); rc = SQLSetDescField( hARD,1, SQL_DESC_DATA_PTR, &dept_no, /* value set to the field*/ SQL_IS_SMALLINT); STMT_HANDLE_CHECK( hstmt1, rc); rc = SQLSetDescField( hARD,2, SQL_DESC_TYPE, (SQLPOINTER)SQL_CHAR, SQL_IS_SMALLINT); STMT_HANDLE_CHECK( hstmt1, rc); rc = SQLSetDescField( hARD,2, SQL_DESC_LENGTH, (SQLPOINTER)15, SQL_IS_INTEGER); STMT_HANDLE_CHECK( hstmt1, rc); rc = SQLSetDescField( hARD,2, SQL_DESC_DATA_PTR, (SQLPOINTER)loc, 15); STMT_HANDLE_CHECK( hstmt1, rc); /* fetch each row, and display */ printf("\n%sFetch rows and dispaly after using SetDescField.\n",sp5); printf("%sDEPTNUMB LOCATION \n",sp8 ) ; printf("%s-------- -------------\n",sp8 ) ; sqlrc = SQLFetch( hstmt1 ); STMT_HANDLE_CHECK( hstmt1, sqlrc); if (sqlrc == SQL_NO_DATA_FOUND) { printf("\n Data not found.\n"); } if (sqlrc == SQL_SUCCESS_WITH_INFO) { printf("\n SUCCESS_WITH_INFO \n"); } while (sqlrc != SQL_NO_DATA_FOUND) { printf( "%s%-8d %s \n", sp8,dept_no, loc ) ; sqlrc = SQLFetch( hstmt1 ); } STMT_HANDLE_CHECK( hstmt1, sqlrc); /* free the statement handle */ sqlrc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); sqlrc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt1 ) ; STMT_HANDLE_CHECK( hstmt, sqlrc); return(rc); }