ODBC drivers >

JDBC drivers >

Bridges, gateways >

Other >

All products

Connect JDBC to any ODBC driver

Connect JDBC to Microsoft Access

Cross-platform or cross-architecture access to any ODBC driver

ODBC access to any JDBC driver

Connect dbExpress applications to any ODBC driver

Connect XML applications to any ODBC driver

Access mutiple ODBC data sources from one SQL statement

Create custom ODBC drivers

Bespoke data access requirements

In the pipeline

Support

Resources

Quick start

Licensing

Knowledge Base

User Guides

Company

About Us

Careers & Partners

Download ODBC Drivers for

Oracle, SQL Server, Salesforce, MongoDB, Access, Derby, InterBase, DB2, & more.

Learn More
/**********************************************************************
* FILENAME : CallSPEditRecord.c
*
* DESCRIPTION :
* Illustrates using a stored procedures to perform several
* actions relating to updating a record into a table. It
* shows how to set up input parameters and how to return a
* status value from the procedure.
*
* Calls a stored procedure as follows:
* {? = CALL Edit_Record (?, ?, ?, ?, ?, ?)}
*
* ODBC USAGE :
* Drops and recreates a procedure Edit_Record().
* Confirms the procedures exist via SQLProcedures ()
* Uses SQLBindParameter() to bind data to the 7
* parameters used in the stored procedure.
*
*	 7 Parameters - 1 - Proc return value - RETURNED
*	 2 - Action - READ, UPDT - INPUT
*	 3 - Record ID - INPUT
*	 4-7 - if action is READ
*	 - old column values - OUTPUT
*	 4-7 - if action is UPDT
*	 - new column values - INPUT
*
*	 Illustrates SELECT, INSERT, UPDATE and DELETE actions via
*	 a stored procedure Edit_Record
*	 			Uses SQLBindParameter() to bind the 7 parameters used with
*	 			the stored procedure Edit_Record() and calls SQLPrepare() to
*	 			make ready for execution.
*
*	 			Uses the notion of current Person ID as current record
*	 			(a value of -1 indicates none). Based on current record and
*	 			action, the program loops executing the stored procedure to
*	 			either Select a specific record, select all records, Update
*	 			or Delete the current record or Insert a new one.
*
*				Selects are either for a single record, or all records.
*				Following a single record select, the record becomes the
*				current record. Following an all records select, there is no
*				current record.
*	 			An insert does not rely on having a current record, but the
*	 			stored procedure returns the record id of the new record, which
*	 			becomes the current record.
*	 			Update relies on having a current record which is kept the same
*	 			during and after the update.
*	 			Delete relies on having a current record but after the delete,
*	 			there is no current record.
*/
#include <stdio.h>
#include <stdlib.h>
#include <sql.h>
#include <sqlext.h>
#include <string.h>
#include "util.c"
#include "CallSPUtil.c"
#define SEL 0 // Action passed to Process_Record() to SELECT single record
#define UPD 1 // Action passed to Process_Record() to UPDATE a record
#define INS 2 // Action passed to Process_Record() to INSERT record
#define DEL 3 // Action passed to Process_Record() to DELETE a record
#define ALL 4 // Action passed to Process_Record() to SELECT ALL records
//
// Function to prompt user for action or record ID. currPID is the current
// record ID, which, if not available (i.e. currPID = -1) removes UPDATE and
// DELETE options (which are dependent on a current record ID) but allows
// SELECT, SELECT all and INSERT (which are not).
//
int getAction (int * currPID) {
 int action=SEL;
 char reply[5];
 printf ("\nNext Action: QUIT (Q)\n"
			"SELECT (Rec No), SELECT All (A), INSERT (I)");
 if (*currPID!=-1) {
 printf (", UPDATE (U), DELETE (D)");
 }
 printf (" ?\n : ");
 reply[0] = ' ';
 fgets(reply, 5, stdin);
 action=SEL;
 if (atoi (reply)==0) {		// Number not entered
 switch (reply[0]) {
 case 'A':
 case 'a':
 action=ALL;		// SELECT all Records
 break;
 case 'I':
 case 'i':
 action=INS;		// INSERT new record
 break;
 case 'U':
 case 'u':
 action=UPD;		// UPDATE current record
 break;
 case 'D':
 case 'd':
 action=DEL;		// DELETE current record
 break;
 case 'Q':
 case 'q':
 default:
 *currPID=0;		// Quit application
 break;
 }
 } else {
 *currPID=(int) atoi (reply);
 }
 return action;
}
int main () {
 SQLHENV henv = SQL_NULL_HENV; 	// Environment
 SQLHDBC hdbc = SQL_NULL_HDBC; 	// Connection handle
 SQLHSTMT hstmt = SQL_NULL_HSTMT; 	// Statement handle
 SQLRETURN retcode;			// Return status
 // Declare call to stored proc with 7 parameter markers
 // Uses 7 Parameters - 1 - Proc return value 	- RETURNED
 // 2 - Action - See below 	- INPUT
 // 3 - RecordID 	- INPUT/OUTOUT
 // 4-7 - if action is SELECT/SELECT ALL
 // - old column values 	- UNUSED
 //							 SELECT is via WHERE RecordID
 //							 SELECT ALL uses no WHERE
 // 4-7 - if action is UPDATE or INSERT
 // - new column values - INPUT
 //							 UPDATE/INSERT is via WHERE RecordID
 //		 	 4-7 - if action is DELETE - UNUSED
 //		 				- Delete is via WHERE RecordID
 SQLCHAR * strCallSP = "{? = CALL Edit_Record (?, ?, ?, ?, ?, ?)}";
 char * strProcName = "Edit_Record";
 char reply[5];
 SQLSMALLINT columns; 				// Number of columns in result-set
 int i, count;
 // Stored proc parameters, input/output variables and return variable.
 SQLCHAR strFirstName[FIRSTNAME_LEN], strLastName[LASTNAME_LEN];
 SQLCHAR strAddress[ADDRESS_LEN], strCity[CITY_LEN];
 SQLLEN lFirstName, lLastName, lAddress, lCity;
 SQLINTEGER	retParam, action, pPersonID=-1, currPID=-1;
 SQLLEN laction, lretParam;
 SQLLEN indicator, rowCount;
 char *buf=malloc (255);
 // Allocate an environment handle
 retcode=SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
 CHECK_ERROR(retcode, "SQLAllocHandle(ENV)", henv, SQL_HANDLE_ENV);
 // Set ODBC Version
 retcode=SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,
 (void *) SQL_OV_ODBC3, 0);
 CHECK_ERROR(retcode, "SQLSetEnvAttr(SQL_ATTR_ODBC_VERSION)",
 henv, SQL_HANDLE_ENV);
 // Allocate a connection handle
 retcode=SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
 CHECK_ERROR(retcode, "SQLAllocHandle(SQL_HANDLE_DBC)",
 hdbc, SQL_HANDLE_DBC);
 // Connect to data source
 retcode=SQLDriverConnect(hdbc, NULL, "DSN=SQLSRV;", SQL_NTS, NULL,
 0, NULL, SQL_DRIVER_COMPLETE);
 CHECK_ERROR(retcode, "SQLDriverConnect(SQLSRV)",
 hdbc, SQL_HANDLE_DBC);
 // Drop previous procedure called Edit_Record
 retcode = DropProcedure (hdbc, strProcName);
 // Create new procedure called Edit_Record
 retcode = CreateProcedure (hdbc, strProcName);
 // Use SQLPRocedures() to show Edit_Record it now available
 retcode = ListProcedure (hdbc, strProcName);
 // Allocate a statement handle
 retcode=SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
 CHECK_ERROR(retcode, "SQLAllocHandle(SQL_HANDLE_STMT)",
 hstmt, SQL_HANDLE_STMT);
 // Bind parameters. The order is the order in which they appear
 // 1st Parameter marker is stored procedure return parameter
 retcode = SQLBindParameter(hstmt, 1, SQL_PARAM_OUTPUT, SQL_C_LONG,
 SQL_INTEGER, 0, 0, &retParam, 0, &lretParam);
 CHECK_ERROR(retcode, "SQLBindParameter(1)", hstmt, SQL_HANDLE_STMT);
 // 2nd Parameter marker is action, passed as INPUT
 retcode = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_LONG,
 SQL_INTEGER, 0, 0, &action, 0, &laction);
 CHECK_ERROR(retcode, "SQLBindParameter(2)", hstmt, SQL_HANDLE_STMT);
 // 3rd Parameter marker is pPersonID, passed as INPUT/OUTPUT
 // Input for SELECT, UPDATE, and DELETE
 // Output for INSERT (returns record inserted)
 retcode = SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT_OUTPUT, SQL_C_LONG,
 SQL_INTEGER, 0, 0, &pPersonID, 0, NULL);
 CHECK_ERROR(retcode, "SQLBindParameter(3)", hstmt, SQL_HANDLE_STMT);
 // 4th Parameter marker is FirstName passed as INPUT
 // Input for INSERT and UPDATE
 retcode = SQLBindParameter(hstmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR,
 SQL_CHAR, FIRSTNAME_LEN, 0, strFirstName,
 FIRSTNAME_LEN, &lFirstName);
 CHECK_ERROR(retcode, "SQLBindParameter(4)", hstmt, SQL_HANDLE_STMT);
 // 5th Parameter marker is LastName passed as INPUT
 // Input for INSERT and UPDATE
 retcode = SQLBindParameter(hstmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR,
 SQL_CHAR, LASTNAME_LEN, 0, strLastName,
 LASTNAME_LEN, &lLastName);
 CHECK_ERROR(retcode, "SQLBindParameter(5)", hstmt, SQL_HANDLE_STMT);
 // 6th Parameter marker is Address passed as INPUT
 // Input for INSERT and UPDATE
 retcode = SQLBindParameter(hstmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR,
 SQL_CHAR, ADDRESS_LEN, 0, strAddress,
 ADDRESS_LEN, &lAddress);
 CHECK_ERROR(retcode, "SQLBindParameter(6)", hstmt, SQL_HANDLE_STMT);
 // 7th Parameter marker is City passed as INPUT
 // Input for INSERT and UPDATE
 retcode = SQLBindParameter(hstmt, 7, SQL_PARAM_INPUT, SQL_C_CHAR,
 SQL_CHAR, CITY_LEN, 0, strCity,
 CITY_LEN, &lCity);
 CHECK_ERROR(retcode, "SQLBindParameter(7)", hstmt, SQL_HANDLE_STMT);
 // Prepare statement with procedure call to Edit_Record()
 retcode = SQLPrepare (hstmt, strCallSP, SQL_NTS);
 CHECK_ERROR(retcode, "SQLPrepare(SQL_HANDLE_STMT)",
 hstmt, SQL_HANDLE_STMT);
 // Get initial action. Returns:
 // 1. Record number to SELECT or 0 to quit
 // 2. 'A' to SELECT all records
 // 3. 'I' to INSERT new record
 action=getAction ((int *) &currPID);
 // Loop while we have a current record.
 while (currPID != 0) {
 pPersonID=currPID;
 if (action != SEL && action != ALL) {
 	 // Not selecting so action is either:
 // 			UPD - Update current record
 // INS - INSERT new record
 // DEL - DELETE current record
 if (action==UPD) {
 // Updating current record
 		// Prompt for replacment column values
 printf ("\nPersonID : %i", pPersonID);
 printf ("\nFirstName : %.10s", strFirstName);
 getStr (" - ", strFirstName, FIRSTNAME_LEN, 'N');
 printf ("LastName : %.10s", strLastName);
 getStr (" - ", strLastName, LASTNAME_LEN, 'N');
 printf ("Address : %.10s", strAddress);
 getStr (" - ", strAddress, ADDRESS_LEN, 'N');
 printf ("City : %.10s", strCity);
 getStr (" - ", strCity, CITY_LEN, 'N');
 }
 if (action==INS) {
 		// Inserting new record
 		// prompt for new record column value
 getStr ("\nFirstName ", strFirstName, FIRSTNAME_LEN, 'N');
 getStr ("LastName ", strLastName, LASTNAME_LEN, 'N');
 getStr ("Address ", strAddress, ADDRESS_LEN, 'N');
 getStr ("City ", strCity, CITY_LEN, 'N');
 }
 if (action==UPD || action==INS) {
 		// If updating or insert, set SQLBindParamater()
 		// StrLen_or_IndPtr values
 lFirstName=strlen(strFirstName);
 lLastName=strlen(strLastName);
 lAddress=strlen(strAddress);
 lCity=strlen(strCity);
 } else {
 		// If deleting current record, prompt to confirm
 printf ("\nDelete Record %i, confirm Y/N ? : ", (int) currPID);
 reply[0] = ' ';
 fgets(reply, 3, stdin);
 if (reply[0]=='Y' || reply[0]=='y') {
 action=DEL;
 		}
 }
 	 // Execute SP for Update, Insert or Delete
 retcode = SQLExecute (hstmt);
 CHECK_ERROR(retcode, "SQLExecute(SQL_HANDLE_STMT)",
 hstmt, SQL_HANDLE_STMT);
 retcode = SQLMoreResults(hstmt);
	 if (retcode != SQL_NO_DATA) {
		CHECK_ERROR(retcode, "SQLMoreResults(SQL_HANDLE_STMT)",
 hstmt, SQL_HANDLE_STMT);
		goto exit;
	 }
 if (action==INS) {
 currPID=pPersonID;
 	 }
 action=SEL;
 }
 	// Clear buffers
 memset (strFirstName, ' ', FIRSTNAME_LEN);
 memset (strLastName, ' ', LASTNAME_LEN);
 memset (strAddress, ' ', ADDRESS_LEN);
 memset (strCity, ' ', CITY_LEN);
 	// Reset buffer lengths
 lFirstName=0;
 lLastName=0;
 lAddress=0;
 lCity=0;
 	// Execute SP for SELECT or SELECT ALL
 retcode = SQLExecute (hstmt);
 CHECK_ERROR(retcode, "SQLExecute(SQL_HANDLE_STMT)",
 hstmt, SQL_HANDLE_STMT);
 	// Loop until SQLMoreResults() says SQL_NO_DATA
 do {
 	 // Get number of columns in results set
 retcode=SQLNumResultCols(hstmt, &columns);
 CHECK_ERROR(retcode, "SQLNumResultCols()", hstmt, SQL_HANDLE_STMT);
 if (columns > 0) {
 			rowCount=0;
 		// Fetch records in results set
 while (SQLFetch(hstmt) != SQL_NO_DATA) {
 	 // Loop through the columns
 		 rowCount++;
 	 memset (buf, ' ', 255);
 printf ("\n");
 		 // Get the column data
 	 for (i = 1; i <= columns; i++) {
 		retcode = SQLGetData(hstmt, i, SQL_C_CHAR,
 buf, 255, &indicator);
 		if (SQL_SUCCEEDED(retcode)) {
 switch (i) {
 case 1:
 pPersonID=atoi(buf);
 break;
 case 2:
 strcpy (strFirstName, buf);
 break;
 case 3:
 strcpy (strLastName, buf);
 break;
 case 4:
 strcpy (strAddress, buf);
 break;
 case 5:
 strcpy (strCity, buf);
 break;
 }
 		}
 	 }
 		 // Display column data
 printf ("\nPersonID : %i", pPersonID);
 printf ("\nFirstName : %.20s", strFirstName);
 printf ("\nLastName : %.20s", strLastName);
 printf ("\nAddress : %.20s", strAddress);
 printf ("\nCity : %.20s", strCity);
 }
 }
 // Check we have a current person ID. If no records found or
 	 // action is ALL records, we don't have a current record so
 	 // set Person ID to -1 which will remove the INSERT and UPDATE
 	 // options from getAction().
 if (rowCount==0) {
 		if (action==SEL) {
 printf ("\nNo Records Matching : %i", (int) pPersonID);
 		}
 // Reset current Person ID
 currPID=-1;
 }
 action=getAction ((int *) &currPID);
 	 if (currPID==0) goto exit;
 } while ((retcode=SQLMoreResults(hstmt)) == SQL_SUCCESS);
 }
exit:
 // Free temporary buffer used for formatting record data
 free (buf);
 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

Download ODBC Drivers for

Oracle, SQL Server, Salesforce, MongoDB, Access, Derby, InterBase, DB2, & more.

Learn More
Share:

AltStyle によって変換されたページ (->オリジナル) /