/******************************************************************************
**
** Source File Name = inpsrv.sqC 1.1
**
** Licensed Materials - Property of IBM
**
** (C) COPYRIGHT International Business Machines Corp. 1995, 1997
** All Rights Reserved.
**
** US Government Users Restricted Rights - Use, duplication or
** disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
**
**
** PURPOSE: This sample program demonstrates stored procedures.
**
** There are two parts to this program:
** - the inpcli executable (placed on the client)
** - the inpsrv library (placed on the server)
**
** The inpsrv function will take the information
** received in the SQLDA to create a table and insert the
** names of the presidents.
**
** Refer to the inpcli.sqC program for more details on how
** this program is invoked as the inpsrv function
** in the inpsrv library by the EXEC SQL CALL statement.
**
** NOTE: One technique to minimize network flow is to set the
** variables that returns no output to null on the server program
** before returning to the client program.
** This can be achieved by setting the value -128 to the
** indicator value associated with the data.
**
** The inpsrv routine will take the information received
** and create a table called "Presidents" in the "sample"
** database. It will then place the values it received in
** the input/output SQLDA into the "Presidents" table.
**
** EXTERNAL DEPENDENCIES :
** - Existing database for precompile purposes.
** - Precompile with the SQL precompiler (PREP in DB2)
** - Binding to a database (BIND in DB2)
** - Compiling and linking with the IBM Cset++ compiler (AIX and OS/2)
** or the Microsoft Visual C++ compiler (Windows)
** or the compiler supported on your platform.
**
** For more information about these samples see the README file.
**
** For more information on programming in C++, see the
** - "Programming in C and C++" section of the Application Development Guide
**
** For more information on building C++ applications, see the:
** - "Building C++ Applications" section of the Application Building Guide.
**
** For more information on the SQL language see the SQL Reference.
**
*******************************************************************************/
#include <memory.h>
#include <string.h>
#include <sqlenv.h>
#include <sqlutil.h>
#include "util.h"
#ifdef __cplusplus
extern "C"
#endif
SQL_API_RC SQL_API_FN inpsrv(void *reserved1, /* :rk.1:erk. */
void *reserved2,
struct sqlda *inout_sqlda,
struct sqlca *ca)
{
/* Declare a local SQLCA */
EXEC SQL INCLUDE SQLCA;
/* Declare Host Variables */
EXEC SQL BEGIN DECLARE SECTION;
char table_stmt[80] = "CREATE TABLE ";
char insert_stmt[80] = "INSERT INTO ";
char insert_data[21];
EXEC SQL END DECLARE SECTION;
/* Declare Miscellanous Variables */
int cntr = 0;
char *table_name;
char *data_items[3];
short data_items_length[3];
int num_of_data = 0;
/*-----------------------------------------------------------------*/
/* Assign the data from the SQLDA to local variables so that we */
/* don't have to refer to the SQLDA structure further. This will */
/* provide better portability to other platforms such as DB2 MVS */
/* where they receive the parameter list differently. */
/*-----------------------------------------------------------------*/
table_name = inout_sqlda->sqlvar[0].sqldata;
num_of_data = inout_sqlda->sqld - 1;
for (cntr = 0; cntr < num_of_data; cntr++)
{
data_items[cntr] = inout_sqlda->sqlvar[cntr+1].sqldata;
data_items_length[cntr] = inout_sqlda->sqlvar[cntr+1].sqllen;
}
/*-----------------------------------------------------------------*/
/* Create President Table */
/* - For simplicity, we'll ignore any errors from the */
/* CREATE TABLE so that you can run this program even when the */
/* table already exists due to a previous run. */
/*-----------------------------------------------------------------*/
EXEC SQL WHENEVER SQLERROR CONTINUE;
strcat(table_stmt, table_name);
strcat(table_stmt, " (name CHAR(20))"); /* :rk.2:erk. */
EXEC SQL EXECUTE IMMEDIATE :table_stmt;
EXEC SQL WHENEVER SQLERROR GOTO ext;
/*-----------------------------------------------------------------*/
/* Generate and execute a PREPARE for an INSERT statement, and */
/* then insert the three presidents. */
/*-----------------------------------------------------------------*/
strcat(insert_stmt, table_name);
strcat(insert_stmt, " VALUES (?)"); /* :rk.3:erk. */
EXEC SQL PREPARE S1 FROM :insert_stmt;
for (cntr = 0; cntr < num_of_data; cntr++)
{
strncpy(insert_data, data_items[cntr], data_items_length[cntr]);
insert_data[data_items_length[cntr]] = '\0';
EXEC SQL EXECUTE S1 USING :insert_data; /* :rk.4:erk. */
}
/*-----------------------------------------------------------------*/
/* Return to caller */
/* - Copy the SQLCA */
/* - Update the output SQLDA. Since there's no output to */
/* return, we are setting the indicator values to -128 to */
/* return only a null value. */
/* - Commit or Rollback the inserts. */
/*-----------------------------------------------------------------*/
ext: /* :rk.5:erk. */
memcpy(ca, &sqlca, sizeof(struct sqlca));
if (inout_sqlda != NULL)
{
for (cntr = 0; cntr < inout_sqlda->sqld; cntr++)
{
*(inout_sqlda->sqlvar[cntr].sqlind) = -128;
}
}
EXEC SQL WHENEVER SQLERROR CONTINUE;
/* Check SQLCA for errors */
if (SQLCODE == 0)
EXEC SQL COMMIT;
else
EXEC SQL ROLLBACK;
return(SQLZ_DISCONNECT_PROC);
}