Here is some simple code in ProC.
#ifndef SQLCA
#include <sqlca.h>
#endif
#define SQLERRM sqlca.sqlerrm.sqlerrmc
/* VTOS */
#define VARCHAR_TO_STRING(src) src.arr[src.len]='\0'
/* VTOV */
#define VARCHAR_TO_VARCHAR(dest, src) dest.len=src.len ; \
strncpy((char *)(dest.arr),(char *)(src.arr), src.len)
/* STOV */
#define STRING_TO_VARCHAR(dest,src) (dest.len = strlen(strcpy((char *)(dest.arr), src))); \
((dest).arr[(dest).len] = (unsigned char)'\0')
/* Uses the .len part to null-terminate the .arr part */
#define NULL_TERM(src) ((src).arr[(src).len] = '\0')
#define SET_LENGTH(src) ((src).len = (strlen(((src).arr))))
/* -------------------------------------------------------------------------------- */
/* TYPE USAGE IN ProC */
/* -------------------------------------------------------------------------------- */
/* THIS IS TO FOOL THE ProC COMPILER AND TELL IT NOT TO SCREAM WHEN IT SEES "sb4" */
EXEC SQL BEGIN DECLARE SECTION;
EXEC SQL TYPE myint IS INTEGER (4);
EXEC SQL END DECLARE SECTION;
/* THIS IS ACTUAL THING THAT C COMPILER USES LATER FOR "sb4", AND
* NOT THE INTEGER(4). NOTE THAT THESE TYPEDEFS MUST ONLY USE THE
* DATA TYPES THAT ProC ALLOWS AS HOST VARIABLES!
* */
typedef int myint;
/* ANOTHER EXAMPLE:
*
* typedef unsigned char *my_raw;
* EXEC SQL TYPE my_raw IS VARRAW(4000) REFERENCE;
* my_raw buffer;
* ...
* buffer = malloc(4004);
*/
/* --------------------------------------------------------------------------------- */
int main()
{
/* DECLARATIONS */
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR connectString[10];
VARCHAR exec_stmt[1000];
VARCHAR l_row2[1000];
myint l_row1;
VARCHAR l_owner[30];
VARCHAR l_table_name[30];
EXEC SQL END DECLARE SECTION;
/* TO DO BULK INSERTS INTO A TABLE (USING ARRAYS)
*
* LATER ALSO USED TO OPEN CURSOR ON THE TABLE AND
* READ THE VALUES, 5 ROWS AT A TIME
*/
EXEC SQL BEGIN DECLARE SECTION;
myint l_row1_arr[5];
VARCHAR l_row2_arr[5][100];
myint bulk_insert_ctr;
EXEC SQL END DECLARE SECTION;
/* INITIALIZATIONS */
char errmsgbuf[512];
int msglength;
int msgbufsize;
int i,j;
long numtab = 0;
long rowsfetched = 0;
long totalrows_fetched = 0;
/* -----------------------------------------------------------*/
/* START : ERROR HANDLING */
/* EXEC SQL WHENEVER NOT FOUND CONTINUE; */
EXEC SQL WHENEVER SQLERROR goto main_fail;
/* END : ERROR HANDLING */
/* -----------------------------------------------------------*/
/* START : CONNECTING TO THE DATABASE */
STRING_TO_VARCHAR(connectString, "apps/apps");
printf("\nConnecting using [%s]....\n",
connectString.arr);
EXEC SQL CONNECT :connectString;
printf("\nConnected.\n\n");
/* END : CONNECTING TO THE DATABASE */
/* ---------------------------------------------------------*/
/* START : DYNAMIC SQL */
STRING_TO_VARCHAR(exec_stmt,
"DROP TABLE A");
EXEC SQL PREPARE S1 FROM :exec_stmt;
printf("\nPrepared : [%s].",
exec_stmt.arr);
EXEC SQL EXECUTE S1;
printf("\nStatement : [%s]."
"\nRows processed : [%d]."
"\nReturn Code : [%d].\n\n",
exec_stmt.arr,
sqlca.sqlerrd[2],
sqlca.sqlcode);
continue1:
STRING_TO_VARCHAR(exec_stmt,
"CREATE TABLE A(ROW1 NUMBER, ROW2 VARCHAR2(100))");
EXEC SQL PREPARE S1 FROM :exec_stmt;
printf("\nPrepared : [%s].",
exec_stmt.arr);
EXEC SQL EXECUTE S1;
printf("\nStatement : [%s]."
"\nRows processed : [%d]."
"\nReturn Code : [%d].\n\n",
exec_stmt.arr,
sqlca.sqlerrd[2],
sqlca.sqlcode);
STRING_TO_VARCHAR(exec_stmt,
"INSERT INTO A VALUES(1,'ABC')");
EXEC SQL PREPARE S1 FROM :exec_stmt;
printf("\nPrepared : [%s].",
exec_stmt.arr);
EXEC SQL EXECUTE S1;
printf("\nStatement : [%s]."
"\nRows processed : [%d]."
"\nReturn Code : [%d].\n\n",
exec_stmt.arr,
sqlca.sqlerrd[2],
sqlca.sqlcode);
/* END : DYNAMIC SQL */
/* ------------------------------------------------------------------------- */
/* START : STATIC SQL */
strcpy(l_row2.arr, "XXXXXXXXXXXXX");
printf("\nSELECT ROW2 FROM A WHERE ROW1 = 1;");
l_row1 = 1;
EXEC SQL
SELECT ROW2 INTO :l_row2
FROM A
where ROW1 = :l_row1;
printf("\nROW2 (BEFORE NULLTERM) : [%s]", l_row2.arr);
NULL_TERM(l_row2); /* DOES l_row2[l_row2.len]='\0'; */
printf("\nROW2 (AFTER NULLTERM) : [%s]\n", l_row2.arr);
printf("\nINSERT INTO A(ROW1, ROW2) SELECT :l_row1, :l_row2 FROM DUAL;");
EXEC SQL
INSERT INTO A(ROW1, ROW2)
select :l_row1, :l_row2 from dual;
printf("\nRows processed : [%d]."
"\nReturn Code : [%d].\n\n",
sqlca.sqlerrd[2],
sqlca.sqlcode);
/* BULK INSERTS INTO TABLE USING ARRAYS */
l_row1_arr[0] = 3;
STRING_TO_VARCHAR(l_row2_arr[0], "CDE");
l_row1_arr[1] = 4;
STRING_TO_VARCHAR(l_row2_arr[1], "DEF");
l_row1_arr[2] = 5;
STRING_TO_VARCHAR(l_row2_arr[2], "EFG");
l_row1_arr[3] = 6;
STRING_TO_VARCHAR(l_row2_arr[3], "FGH");
l_row1_arr[4] = 7;
STRING_TO_VARCHAR(l_row2_arr[4], "GHI");
/* THIS WILL INSERT ALL 5 ELEMENTS OF THE ARRAY */
EXEC SQL
INSERT INTO A(ROW1, ROW2)
VALUES (:l_row1_arr, :l_row2_arr);
printf("\nRows processed : [%d]."
"\nReturn Code : [%d].\n\n",
sqlca.sqlerrd[2],
sqlca.sqlcode);
EXEC SQL COMMIT;
l_row1_arr[0] = 8;
STRING_TO_VARCHAR(l_row2_arr[0], "HIJ");
l_row1_arr[1] = 9;
STRING_TO_VARCHAR(l_row2_arr[1], "IJK");
l_row1_arr[2] = 10;
/* THIS WILL ONLY INSERT 3 ROWS INTO THE TABLE, ALTHOUGH THE
* ARRAYS CAN ACCOMODATE MAX OF 5 ELEMENTS */
bulk_insert_ctr = 3;
EXEC SQL FOR :bulk_insert_ctr
INSERT INTO A(ROW1, ROW2)
VALUES (:l_row1_arr, :l_row2_arr);
printf("\nRows processed : [%d]."
"\nReturn Code : [%d].\n\n",
sqlca.sqlerrd[2],
sqlca.sqlcode);
/* The USUAL idea with these bulk inserts is to do something like this
*
* bulk_insert_ctr = 0;
*
* while(<say_reading_something_from_a_file>)
* {
* if(bulk_insert_ctr >= MAX_ARRAY_SIZE_WHICH_WE_HAVE)
* {
* EXEC SQL
* INSERT INTO <SOMETHING> (COL1, COL2, ....)
* VALUES (:l_col1_array, :l_col2_array, .....);
*
* EXEC SQL COMMIT;
*
* bulk_insert_ctr = 0;
*
* }
*
* >> KEEP FILLING THE ARRAYS TILL WE REACH THE LIMIT OF
* >> MAX_ARRAY_SIZE_WHICH_WE_HAVE
*
* l_col1_array[bulk_insert_ctr] = <something>;
* STRING_TO_VARCHAR(l_col2_arr[bulk_insert_ctr], "<something>");
*
* bulk_insert_ctr++;
*
* }//while loop
*
* >> HERE DO INSERTS FOR ANY RESIDUAL DATA THAT MIGHT HAVE
* >> ACCUMULATED INTO OUR LOCAL ARRAYS.
*
* >> NOTICE THE USE OF "FOR :bulk_insert_ctr" HERE
*
* EXEC SQL FOR :bulk_insert_ctr
* INSERT INTO <SOMETHING> (COL1, COL2, ....)
* VALUES (:l_col1_array, :l_col2_array, .....);
*
* EXEC SQL COMMIT;
*
* bulk_insert_ctr = 0;
*
*
*
*
*
* ALSO NOTE THAT IF WE WISH TO INSERT A CONSTANT VALUE (say APPL_TOP_ID,
* which is determined at run-time), WE CANNOT USE A SINGLE VARIABLE LIKE
* l_appL_top_id AND USE IT IN THE BULK INSERT!
*
* EVEN THIS NEEDS TO BE AN ARRAY l_appl_top_id[MAX_ARRAY_SIZE], EVENTHOUGH
* THIS WOULD MEANS DUPLICATION OF APPL_TOP_ID IN ALL THE ARRAY ELEMENTS!
*
* NOTE THAT YOU CAN ALWAYS USE SOMETHING LIKE '1' OR SYSDATE THOUGH, THE
* ABOVE RESTRICTION IS ONLY FOR A RUN_TIME VARIABLE THAT REMAINS SAME
* FOR ALL THE INSERTS....
*
*/
/* END : STATIC SQL */
/* -------------------------------------------------------------------------- */
/* START : CALLING A PL/SQL PROCEDURE */
STRING_TO_VARCHAR(l_owner, "APPS");
STRING_TO_VARCHAR(l_table_name, "A");
STRING_TO_VARCHAR(exec_stmt,"");
/* BUILD UP THE SQL STATEMENT */
strcat(exec_stmt.arr, "\nBEGIN");
strcat(exec_stmt.arr, "\nFND_STATS.GATHER_TABLE_STATS");
strcat(exec_stmt.arr, "\n(");
strcat(exec_stmt.arr, "\n:owner, :tab_name");
strcat(exec_stmt.arr, "\n);");
strcat(exec_stmt.arr, "\nEND;");
SET_LENGTH(exec_stmt);
EXEC SQL PREPARE S1 FROM :exec_stmt;
printf("\nPrepared : [%s].",
exec_stmt.arr);
EXEC SQL EXECUTE S1 USING :l_owner, :l_table_name;
printf("\nStatement : [%s]."
"\nRows processed : [%d]."
"\nReturn Code : [%d].\n\n",
exec_stmt.arr,
sqlca.sqlerrd[2],
sqlca.sqlcode);
/* END : CALLING A PL/SQL PROCEDURE */
/* ------------------------------------------------------------------------- */
/* START : CURSORS */
printf("\n SPOOLING THE DATA IN THE TABLE\n");
printf("\n----------------------------------------------\n");
printf("ROW1 ROW2");
printf("\n----------------------------------------------\n");
STRING_TO_VARCHAR(exec_stmt,"");
sprintf(exec_stmt.arr, "SELECT ROW1, ROW2 FROM A");
SET_LENGTH(exec_stmt);
EXEC SQL PREPARE S1 FROM :exec_stmt;
EXEC SQL DECLARE mycursor CURSOR FOR S1;
EXEC SQL OPEN mycursor;
while(1)
{
/* Fetch 5 rows at a time */
EXEC SQL FETCH mycursor
INTO :l_row1_arr, :l_row2_arr;
rowsfetched = sqlca.sqlerrd[2] - numtab;
totalrows_fetched = sqlca.sqlerrd[2];
numtab = sqlca.sqlerrd[2];
for(i=0; i<rowsfetched; i++)
{
NULL_TERM(l_row2_arr[i]);
printf("\n[%d] [%s]\n", l_row1_arr[i], l_row2_arr[i].arr);
}
if(sqlca.sqlcode == 1403)break;
}
EXEC SQL CLOSE mycursor;
printf("\n----------------------------------------------\n");
/* END : CURSORS */
/* ------------------------------------------------------------------------ */
/* START : USING INDICATORS */
/*
*
* EXEC SQL BEGIN DECLARE SECTION;
* varchar l_ret_cd[4];
* short l_ret_cd_ind = 0;
* EXEC SQL END DECLARE SECTION;
*
* EXEC SQL EXECUTE S1 USING :l_rlse_id, :l_at_id, :l_ret_cd:l_ret_cd_ind;
*
* if (l_ret_cd_ind == -1)
* STOV(l_ret_cd, "");
*
* nullterm(l_ret_cd);
*
* if (!strcmp((char *)l_ret_cd.arr, "AI"))
*
*
*
* THE SAME CAN BE USED WHILE INSERTING VALUES INTO TABLES
*/
/*
* EXEC SQL BEGIN DECLARE SECTION;
* VARCHAR sql_statemt[400];
* VARCHAR v_mode[200];
* short v_ind_mode;
* EXEC SQL END DECLARE SECTION;
*
* STRING_TO_VARCHAR(sql_statemt, "");
*
* strcat((char *)sql_statemt.arr, "\nBegin");
* strcat((char *)sql_statemt.arr,"\n:p_no_of_rep_ctr:=");
* strcat((char *)sql_statemt.arr,"\nUTIL.");
* strcat((char *)sql_statemt.arr,"GET_CURRENT_MODE;");
* strcat((char *)sql_statemt.arr, "\nEnd;");
* setlen(sql_statemt);
*
* EXEC SQL PREPARE S1 FROM
* :sql_statemt;
*
* EXEC SQL EXECUTE S1 USING
* :v_mode:v_ind_mode;
*
* nullterm(v_mode);
*
*/
/* END : USING INDICATORS */
/* ------------------------------------------------------------------------- */
/* Commiting, disconencting, rolbacking ...
*
* EXEC SQL COMMIT WORK;
*
* EXEC SQL COMMIT WORK RELEASE;
*
* EXEC SQL ROLLBACK WORK;
*
* EXEC SQL ROLLBACK WORK RELEASE;
*
*/
EXEC SQL COMMIT WORK RELEASE;
/* -------------------------------------------------------------------- */
/* START : IMPORTANT OPTIONS OR CODE SNIPPETS */
/*
* EXEC ORACLE OPTION (HOLD_CURSOR=YES);
*
*
*
* EXEC SQL
* SELECT 'X'
* INTO :l_dummy
* FROM ACTIONS
* WHERE BUG_ID = :l_bug_id
* AND FILE_ID = :l_file_id
* AND ACTION_ID = :l_act_id;
*
* if (sqlca.sqlcode == 0)
* {
* *is_a_dup = TRUE;
* return TRUE;
* }
*
*
*
*
*
* EXEC SQL LOCK TABLE IN EXCLUSIVE MODE NOWAIT;
*
*
*
*
*
*
*
* EXEC SQL DECLARE C_DRVR CURSOR FOR
* SELECT
* APPLIED_PATCH_ID, PATCH_DRIVER_ID
* FROM
* PATCH_DRIVERS
* WHERE DRIVER_FILE_NAME = :v_driverfile_name
* AND NVL(DRIVER_TYPE_C_FLAG, 'N') = NVL(:v_driver_type_c, 'N')
* AND NVL(DRIVER_TYPE_D_FLAG, 'N') = NVL(:v_driver_type_d, 'N')
* AND NVL(DRIVER_TYPE_G_FLAG, 'N') = NVL(:v_driver_type_g, 'N')
* AND PLATFORM = :v_platform
* AND PLATFORM_VERSION = :v_platform_version
* AND FILE_SIZE = :v_file_size
* AND FILE_CONTENTS_CHECKSUM = :v_check_sum;
*
*
*
*/
/* END : IMPORTANT OPTIONS OR CODE SNIPPETS */
/* -------------------------------------------------------------------- */
return(0);
main_fail:
if(sqlca.sqlcode == -942)
{
goto continue1;
}
else if (sqlca.sqlcode != 0 )
{
msgbufsize = 512;
sqlglm(errmsgbuf, &msgbufsize, &msglength);
errmsgbuf[(msglength < msgbufsize)? msglength : msgbufsize] = '\0';
printf("\nAn error occurred\n\n"
"Code : [%d]\n"
"Description : [%s]\n\n",
sqlca.sqlcode,
errmsgbuf);
}
return(1);
}
Here is a sample output for this file
sh-2.05$ /home/sgadag/tmp/practice/ProC/myexe
Connecting using [apps/apps]....
Connected.
Prepared : [DROP TABLE A].
Statement : [DROP TABLE A].
Rows processed : [0].
Return Code : [0].
Prepared : [CREATE TABLE A(ROW1 NUMBER, ROW2 VARCHAR2(100))].
Statement : [CREATE TABLE A(ROW1 NUMBER, ROW2 VARCHAR2(100))].
Rows processed : [0].
Return Code : [0].
Prepared : [INSERT INTO A VALUES(1,'ABC')].
Statement : [INSERT INTO A VALUES(1,'ABC')].
Rows processed : [1].
Return Code : [0].
SELECT ROW2 FROM A WHERE ROW1 = 1;
ROW2 (BEFORE NULLTERM) : [ABCXXXXXXXXXX]
ROW2 (AFTER NULLTERM) : [ABC]
INSERT INTO A(ROW1, ROW2) SELECT :l_row1, :l_row2 FROM DUAL;
Rows processed : [1].
Return Code : [0].
Rows processed : [5].
Return Code : [0].
Rows processed : [3].
Return Code : [0].
Prepared : [
BEGIN
FND_STATS.GATHER_TABLE_STATS
(
:owner, :tab_name
);
END;].
Statement : [
BEGIN
FND_STATS.GATHER_TABLE_STATS
(
:owner, :tab_name
);
END;].
Rows processed : [1].
Return Code : [0].
SPOOLING THE DATA IN THE TABLE
----------------------------------------------
ROW1 ROW2
----------------------------------------------
[1] [ABC]
[1] [ABC]
[3] [CDE]
[4] [DEF]
[5] [EFG]
[6] [FGH]
[7] [GHI]
[8] [HIJ]
[9] [IJK]
[10] [EFG]
----------------------------------------------
sh-2.05$
This code gets preprocessed into something like this (using the ProC preprocessor)
/* Result Sets Interface */
#ifndef SQL_CRSR
# define SQL_CRSR
struct sql_cursor
{
unsigned int curocn;
void *ptr1;
void *ptr2;
unsigned int magic;
};
typedef struct sql_cursor sql_cursor;
typedef struct sql_cursor SQL_CURSOR;
#endif /* SQL_CRSR */
/* Thread Safety */
typedef void * sql_context;
typedef void * SQL_CONTEXT;
/* Object support */
struct sqltvn
{
unsigned char *tvnvsn;
unsigned short tvnvsnl;
unsigned char *tvnnm;
unsigned short tvnnml;
unsigned char *tvnsnm;
unsigned short tvnsnml;
};
typedef struct sqltvn sqltvn;
struct sqladts
{
unsigned int adtvsn;
unsigned short adtmode;
unsigned short adtnum;
sqltvn adttvn[1];
};
typedef struct sqladts sqladts;
static struct sqladts sqladt = {
1,1,0,
};
/* Binding to PL/SQL Records */
struct sqltdss
{
unsigned int tdsvsn;
unsigned short tdsnum;
unsigned char *tdsval[1];
};
typedef struct sqltdss sqltdss;
static struct sqltdss sqltds =
{
1,
0,
};
/* File name & Package Name */
struct sqlcxp
{
unsigned short fillen;
char filnam[9];
};
static struct sqlcxp sqlfpn =
{
8,
"ProC.opc"
};
static const unsigned int sqlctx = 1102759285;
static struct sqlexd {
unsigned int sqlvsn;
unsigned int arrsiz;
unsigned int iters;
unsigned int offset;
unsigned short selerr;
unsigned short sqlety;
unsigned int unused;
short *cud;
unsigned char *sqlest;
char *stmt;
sqladts *sqladtp;
sqltdss *sqltdsp;
void **sqphsv;
unsigned int *sqphsl;
int *sqphss;
void **sqpind;
int *sqpins;
unsigned int *sqparm;
unsigned int **sqparc;
unsigned short *sqpadto;
unsigned short *sqptdso;
void *sqhstv[4];
unsigned int sqhstl[4];
int sqhsts[4];
void *sqindv[4];
int sqinds[4];
unsigned int sqharm[4];
unsigned int *sqharc[4];
unsigned short sqadto[4];
unsigned short sqtdso[4];
} sqlstm = {10,4};
/* SQLLIB Prototypes */
extern sqlcxt (/*_ void **, unsigned int *,
struct sqlexd *, struct sqlcxp * _*/);
extern sqlcx2t(/*_ void **, unsigned int ,
struct sqlexd *, struct sqlcxp * _*/);
extern sqlbuft(/*_ void **, char * _*/);
extern sqlgs2t(/*_ void **, char * _*/);
extern sqlorat(/*_ void **, unsigned int *, void * _*/);
/* Forms Interface */
static int IAPSUCC = 0;
static int IAPFAIL = 1403;
static int IAPFTL = 535;
extern void sqliem(/*_ char *, int * _*/);
typedef struct { unsigned short len; unsigned char arr[1]; } VARCHAR;
typedef struct { unsigned short len; unsigned char arr[1]; } varchar;
/* CUD (Compilation Unit Data) Array */
static short sqlcud0[] =
{10,4274,0,0,0,
5,0,0,1,0,0,283,111,0,0,4,4,0,1,0,1,9,0,0,1,10,0,0,1,10,0,0,1,10,0,0,
36,0,0,2,0,0,273,125,0,0,1,1,0,1,0,1,9,0,0,
55,0,0,2,0,0,277,130,0,0,0,0,0,1,0,
70,0,0,2,0,0,273,144,0,0,1,1,0,1,0,1,9,0,0,
89,0,0,2,0,0,277,149,0,0,0,0,0,1,0,
104,0,0,2,0,0,273,161,0,0,1,1,0,1,0,1,9,0,0,
123,0,0,2,0,0,277,166,0,0,0,0,0,1,0,
138,0,0,3,43,0,260,189,0,0,2,1,0,1,0,2,9,0,0,1,3,0,0,
161,0,0,4,51,0,259,203,0,0,2,2,0,1,0,1,3,0,0,1,9,0,0,
184,0,0,5,41,0,259,230,0,0,2,2,0,1,0,1,3,0,0,1,9,0,0,
207,0,0,6,0,0,285,240,0,0,0,0,0,1,0,
222,0,0,7,41,0,259,257,0,0,2,2,0,1,0,1,3,0,0,1,9,0,0,
245,0,0,2,0,0,273,351,0,0,1,1,0,1,0,1,9,0,0,
264,0,0,2,0,0,277,356,0,0,2,2,0,1,0,1,9,0,0,1,9,0,0,
287,0,0,2,0,0,273,384,0,0,1,1,0,1,0,1,9,0,0,
306,0,0,2,0,0,301,387,0,0,0,0,0,1,0,
321,0,0,2,0,0,269,392,0,0,2,0,0,1,0,2,3,0,0,2,9,0,0,
344,0,0,2,0,0,271,409,0,0,0,0,0,1,0,
359,0,0,8,0,0,286,487,0,0,0,0,0,1,0,
};
#ifndef SQLCA
#include <sqlca.h>
#endif
#define SQLERRM sqlca.sqlerrm.sqlerrmc
/* VTOS */
#define VARCHAR_TO_STRING(src) src.arr[src.len]='\0'
/* VTOV */
#define VARCHAR_TO_VARCHAR(dest, src) dest.len=src.len ; \
strncpy((char *)(dest.arr),(char *)(src.arr), src.len)
/* STOV */
#define STRING_TO_VARCHAR(dest,src) (dest.len = strlen(strcpy((char *)(dest.arr), src))); \
((dest).arr[(dest).len] = (unsigned char)'\0')
/* Uses the .len part to null-terminate the .arr part */
#define NULL_TERM(src) ((src).arr[(src).len] = '\0')
#define SET_LENGTH(src) ((src).len = (strlen(((src).arr))))
/* -------------------------------------------------------------------------------- */
/* TYPE USAGE IN ProC */
/* -------------------------------------------------------------------------------- */
/* THIS IS TO FOOL THE ProC COMPILER AND TELL IT NOT TO SCREAM WHEN IT SEES "sb4" */
/* EXEC SQL BEGIN DECLARE SECTION; */
/* EXEC SQL TYPE myint IS INTEGER (4); */
/* EXEC SQL END DECLARE SECTION; */
/* THIS IS ACTUAL THING THAT C COMPILER USES LATER FOR "sb4", AND
* NOT THE INTEGER(4). NOTE THAT THESE TYPEDEFS MUST ONLY USE THE
* DATA TYPES THAT ProC ALLOWS AS HOST VARIABLES!
* */
typedef int myint;
/* ANOTHER EXAMPLE:
*
* typedef unsigned char *my_raw;
* EXEC SQL TYPE my_raw IS VARRAW(4000) REFERENCE;
* my_raw buffer;
* ...
* buffer = malloc(4004);
*/
/* --------------------------------------------------------------------------------- */
int main()
{
/* DECLARATIONS */
/* EXEC SQL BEGIN DECLARE SECTION; */
/* VARCHAR connectString[10]; */
struct { unsigned short len; unsigned char arr[10]; } connectString;
/* VARCHAR exec_stmt[1000]; */
struct { unsigned short len; unsigned char arr[1000]; } exec_stmt;
/* VARCHAR l_row2[1000]; */
struct { unsigned short len; unsigned char arr[1000]; } l_row2;
myint l_row1;
/* VARCHAR l_owner[30]; */
struct { unsigned short len; unsigned char arr[30]; } l_owner;
/* VARCHAR l_table_name[30]; */
struct { unsigned short len; unsigned char arr[30]; } l_table_name;
/* EXEC SQL END DECLARE SECTION; */
/* TO DO BULK INSERTS INTO A TABLE (USING ARRAYS)
*
* LATER ALSO USED TO OPEN CURSOR ON THE TABLE AND
* READ THE VALUES, 5 ROWS AT A TIME
*/
/* EXEC SQL BEGIN DECLARE SECTION; */
myint l_row1_arr[5];
/* VARCHAR l_row2_arr[5][100]; */
struct { unsigned short len; unsigned char arr[102]; } l_row2_arr[5];
myint bulk_insert_ctr;
/* EXEC SQL END DECLARE SECTION; */
/* INITIALIZATIONS */
char errmsgbuf[512];
int msglength;
int msgbufsize;
int i,j;
long numtab = 0;
long rowsfetched = 0;
long totalrows_fetched = 0;
/* -----------------------------------------------------------*/
/* START : ERROR HANDLING */
/* EXEC SQL WHENEVER NOT FOUND CONTINUE; */
/* EXEC SQL WHENEVER SQLERROR goto main_fail; */
/* END : ERROR HANDLING */
/* -----------------------------------------------------------*/
/* START : CONNECTING TO THE DATABASE */
STRING_TO_VARCHAR(connectString, "apps/apps");
printf("\nConnecting using [%s]....\n",
connectString.arr);
/* EXEC SQL CONNECT :connectString; */
{
struct sqlexd sqlstm;
sqlstm.sqlvsn = 10;
sqlstm.arrsiz = 4;
sqlstm.sqladtp = &sqladt;
sqlstm.sqltdsp = &sqltds;
sqlstm.iters = (unsigned int )100;
sqlstm.offset = (unsigned int )5;
sqlstm.cud = sqlcud0;
sqlstm.sqlest = (unsigned char *)&sqlca;
sqlstm.sqlety = (unsigned short)0;
sqlstm.sqhstv[0] = ( void *)&connectString;
sqlstm.sqhstl[0] = (unsigned int )12;
sqlstm.sqhsts[0] = ( int )12;
sqlstm.sqindv[0] = ( void *)0;
sqlstm.sqinds[0] = ( int )0;
sqlstm.sqharm[0] = (unsigned int )0;
sqlstm.sqadto[0] = (unsigned short )0;
sqlstm.sqtdso[0] = (unsigned short )0;
sqlstm.sqphsv = sqlstm.sqhstv;
sqlstm.sqphsl = sqlstm.sqhstl;
sqlstm.sqphss = sqlstm.sqhsts;
sqlstm.sqpind = sqlstm.sqindv;
sqlstm.sqpins = sqlstm.sqinds;
sqlstm.sqparm = sqlstm.sqharm;
sqlstm.sqparc = sqlstm.sqharc;
sqlstm.sqpadto = sqlstm.sqadto;
sqlstm.sqptdso = sqlstm.sqtdso;
sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
if (sqlca.sqlcode < 0) goto main_fail;
}
printf("\nConnected.\n\n");
/* END : CONNECTING TO THE DATABASE */
/* ---------------------------------------------------------*/
/* START : DYNAMIC SQL */
STRING_TO_VARCHAR(exec_stmt,
"DROP TABLE A");
/* EXEC SQL PREPARE S1 FROM :exec_stmt; */
{
struct sqlexd sqlstm;
sqlstm.sqlvsn = 10;
sqlstm.arrsiz = 4;
sqlstm.sqladtp = &sqladt;
sqlstm.sqltdsp = &sqltds;
sqlstm.stmt = "";
sqlstm.iters = (unsigned int )1;
sqlstm.offset = (unsigned int )36;
sqlstm.cud = sqlcud0;
sqlstm.sqlest = (unsigned char *)&sqlca;
sqlstm.sqlety = (unsigned short)0;
sqlstm.sqhstv[0] = ( void *)&exec_stmt;
sqlstm.sqhstl[0] = (unsigned int )1002;
sqlstm.sqhsts[0] = ( int )0;
sqlstm.sqindv[0] = ( void *)0;
sqlstm.sqinds[0] = ( int )0;
sqlstm.sqharm[0] = (unsigned int )0;
sqlstm.sqadto[0] = (unsigned short )0;
sqlstm.sqtdso[0] = (unsigned short )0;
sqlstm.sqphsv = sqlstm.sqhstv;
sqlstm.sqphsl = sqlstm.sqhstl;
sqlstm.sqphss = sqlstm.sqhsts;
sqlstm.sqpind = sqlstm.sqindv;
sqlstm.sqpins = sqlstm.sqinds;
sqlstm.sqparm = sqlstm.sqharm;
sqlstm.sqparc = sqlstm.sqharc;
sqlstm.sqpadto = sqlstm.sqadto;
sqlstm.sqptdso = sqlstm.sqtdso;
sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
if (sqlca.sqlcode < 0) goto main_fail;
}
printf("\nPrepared : [%s].",
exec_stmt.arr);
/* EXEC SQL EXECUTE S1; */
{
struct sqlexd sqlstm;
sqlstm.sqlvsn = 10;
sqlstm.arrsiz = 4;
sqlstm.sqladtp = &sqladt;
sqlstm.sqltdsp = &sqltds;
sqlstm.stmt = "";
sqlstm.iters = (unsigned int )1;
sqlstm.offset = (unsigned int )55;
sqlstm.cud = sqlcud0;
sqlstm.sqlest = (unsigned char *)&sqlca;
sqlstm.sqlety = (unsigned short)0;
sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
if (sqlca.sqlcode < 0) goto main_fail;
}
printf("\nStatement : [%s]."
"\nRows processed : [%d]."
"\nReturn Code : [%d].\n\n",
exec_stmt.arr,
sqlca.sqlerrd[2],
sqlca.sqlcode);
continue1:
STRING_TO_VARCHAR(exec_stmt,
"CREATE TABLE A(ROW1 NUMBER, ROW2 VARCHAR2(100))");
/* EXEC SQL PREPARE S1 FROM :exec_stmt; */
{
struct sqlexd sqlstm;
sqlstm.sqlvsn = 10;
sqlstm.arrsiz = 4;
sqlstm.sqladtp = &sqladt;
sqlstm.sqltdsp = &sqltds;
sqlstm.stmt = "";
sqlstm.iters = (unsigned int )1;
sqlstm.offset = (unsigned int )70;
sqlstm.cud = sqlcud0;
sqlstm.sqlest = (unsigned char *)&sqlca;
sqlstm.sqlety = (unsigned short)0;
sqlstm.sqhstv[0] = ( void *)&exec_stmt;
sqlstm.sqhstl[0] = (unsigned int )1002;
sqlstm.sqhsts[0] = ( int )0;
sqlstm.sqindv[0] = ( void *)0;
sqlstm.sqinds[0] = ( int )0;
sqlstm.sqharm[0] = (unsigned int )0;
sqlstm.sqadto[0] = (unsigned short )0;
sqlstm.sqtdso[0] = (unsigned short )0;
sqlstm.sqphsv = sqlstm.sqhstv;
sqlstm.sqphsl = sqlstm.sqhstl;
sqlstm.sqphss = sqlstm.sqhsts;
sqlstm.sqpind = sqlstm.sqindv;
sqlstm.sqpins = sqlstm.sqinds;
sqlstm.sqparm = sqlstm.sqharm;
sqlstm.sqparc = sqlstm.sqharc;
sqlstm.sqpadto = sqlstm.sqadto;
sqlstm.sqptdso = sqlstm.sqtdso;
sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
if (sqlca.sqlcode < 0) goto main_fail;
}
printf("\nPrepared : [%s].",
exec_stmt.arr);
/* EXEC SQL EXECUTE S1; */
{
struct sqlexd sqlstm;
sqlstm.sqlvsn = 10;
sqlstm.arrsiz = 4;
sqlstm.sqladtp = &sqladt;
sqlstm.sqltdsp = &sqltds;
sqlstm.stmt = "";
sqlstm.iters = (unsigned int )1;
sqlstm.offset = (unsigned int )89;
sqlstm.cud = sqlcud0;
sqlstm.sqlest = (unsigned char *)&sqlca;
sqlstm.sqlety = (unsigned short)0;
sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
if (sqlca.sqlcode < 0) goto main_fail;
}
printf("\nStatement : [%s]."
"\nRows processed : [%d]."
"\nReturn Code : [%d].\n\n",
exec_stmt.arr,
sqlca.sqlerrd[2],
sqlca.sqlcode);
STRING_TO_VARCHAR(exec_stmt,
"INSERT INTO A VALUES(1,'ABC')");
/* EXEC SQL PREPARE S1 FROM :exec_stmt; */
{
struct sqlexd sqlstm;
sqlstm.sqlvsn = 10;
sqlstm.arrsiz = 4;
sqlstm.sqladtp = &sqladt;
sqlstm.sqltdsp = &sqltds;
sqlstm.stmt = "";
sqlstm.iters = (unsigned int )1;
sqlstm.offset = (unsigned int )104;
sqlstm.cud = sqlcud0;
sqlstm.sqlest = (unsigned char *)&sqlca;
sqlstm.sqlety = (unsigned short)0;
sqlstm.sqhstv[0] = ( void *)&exec_stmt;
sqlstm.sqhstl[0] = (unsigned int )1002;
sqlstm.sqhsts[0] = ( int )0;
sqlstm.sqindv[0] = ( void *)0;
sqlstm.sqinds[0] = ( int )0;
sqlstm.sqharm[0] = (unsigned int )0;
sqlstm.sqadto[0] = (unsigned short )0;
sqlstm.sqtdso[0] = (unsigned short )0;
sqlstm.sqphsv = sqlstm.sqhstv;
sqlstm.sqphsl = sqlstm.sqhstl;
sqlstm.sqphss = sqlstm.sqhsts;
sqlstm.sqpind = sqlstm.sqindv;
sqlstm.sqpins = sqlstm.sqinds;
sqlstm.sqparm = sqlstm.sqharm;
sqlstm.sqparc = sqlstm.sqharc;
sqlstm.sqpadto = sqlstm.sqadto;
sqlstm.sqptdso = sqlstm.sqtdso;
sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
if (sqlca.sqlcode < 0) goto main_fail;
}
printf("\nPrepared : [%s].",
exec_stmt.arr);
/* EXEC SQL EXECUTE S1; */
{
struct sqlexd sqlstm;
sqlstm.sqlvsn = 10;
sqlstm.arrsiz = 4;
sqlstm.sqladtp = &sqladt;
sqlstm.sqltdsp = &sqltds;
sqlstm.stmt = "";
sqlstm.iters = (unsigned int )1;
sqlstm.offset = (unsigned int )123;
sqlstm.cud = sqlcud0;
sqlstm.sqlest = (unsigned char *)&sqlca;
sqlstm.sqlety = (unsigned short)0;
sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
if (sqlca.sqlcode < 0) goto main_fail;
}
printf("\nStatement : [%s]."
"\nRows processed : [%d]."
"\nReturn Code : [%d].\n\n",
exec_stmt.arr,
sqlca.sqlerrd[2],
sqlca.sqlcode);
/* END : DYNAMIC SQL */
/* ------------------------------------------------------------------------- */
/* START : STATIC SQL */
strcpy(l_row2.arr, "XXXXXXXXXXXXX");
printf("\nSELECT ROW2 FROM A WHERE ROW1 = 1;");
l_row1 = 1;
/* EXEC SQL
SELECT ROW2 INTO :l_row2
FROM A
where ROW1 = :l_row1; */
{
struct sqlexd sqlstm;
sqlstm.sqlvsn = 10;
sqlstm.arrsiz = 4;
sqlstm.sqladtp = &sqladt;
sqlstm.sqltdsp = &sqltds;
sqlstm.stmt = "select ROW2 into :b0 from A where ROW1=:b1";
sqlstm.iters = (unsigned int )1;
sqlstm.offset = (unsigned int )138;
sqlstm.selerr = (unsigned short)1;
sqlstm.cud = sqlcud0;
sqlstm.sqlest = (unsigned char *)&sqlca;
sqlstm.sqlety = (unsigned short)0;
sqlstm.sqhstv[0] = ( void *)&l_row2;
sqlstm.sqhstl[0] = (unsigned int )1002;
sqlstm.sqhsts[0] = ( int )0;
sqlstm.sqindv[0] = ( void *)0;
sqlstm.sqinds[0] = ( int )0;
sqlstm.sqharm[0] = (unsigned int )0;
sqlstm.sqadto[0] = (unsigned short )0;
sqlstm.sqtdso[0] = (unsigned short )0;
sqlstm.sqhstv[1] = ( void *)&l_row1;
sqlstm.sqhstl[1] = (unsigned int )4;
sqlstm.sqhsts[1] = ( int )0;
sqlstm.sqindv[1] = ( void *)0;
sqlstm.sqinds[1] = ( int )0;
sqlstm.sqharm[1] = (unsigned int )0;
sqlstm.sqadto[1] = (unsigned short )0;
sqlstm.sqtdso[1] = (unsigned short )0;
sqlstm.sqphsv = sqlstm.sqhstv;
sqlstm.sqphsl = sqlstm.sqhstl;
sqlstm.sqphss = sqlstm.sqhsts;
sqlstm.sqpind = sqlstm.sqindv;
sqlstm.sqpins = sqlstm.sqinds;
sqlstm.sqparm = sqlstm.sqharm;
sqlstm.sqparc = sqlstm.sqharc;
sqlstm.sqpadto = sqlstm.sqadto;
sqlstm.sqptdso = sqlstm.sqtdso;
sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
if (sqlca.sqlcode < 0) goto main_fail;
}
printf("\nROW2 (BEFORE NULLTERM) : [%s]", l_row2.arr);
NULL_TERM(l_row2); /* DOES l_row2[l_row2.len]='\0'; */
printf("\nROW2 (AFTER NULLTERM) : [%s]\n", l_row2.arr);
printf("\nINSERT INTO A(ROW1, ROW2) SELECT :l_row1, :l_row2 FROM DUAL;");
/* EXEC SQL
INSERT INTO A(ROW1, ROW2)
select :l_row1, :l_row2 from dual; */
{
struct sqlexd sqlstm;
sqlstm.sqlvsn = 10;
sqlstm.arrsiz = 4;
sqlstm.sqladtp = &sqladt;
sqlstm.sqltdsp = &sqltds;
sqlstm.stmt = "insert into A(ROW1,ROW2)select :b0 ,:b1 from dual ";
sqlstm.iters = (unsigned int )1;
sqlstm.offset = (unsigned int )161;
sqlstm.cud = sqlcud0;
sqlstm.sqlest = (unsigned char *)&sqlca;
sqlstm.sqlety = (unsigned short)0;
sqlstm.sqhstv[0] = ( void *)&l_row1;
sqlstm.sqhstl[0] = (unsigned int )4;
sqlstm.sqhsts[0] = ( int )0;
sqlstm.sqindv[0] = ( void *)0;
sqlstm.sqinds[0] = ( int )0;
sqlstm.sqharm[0] = (unsigned int )0;
sqlstm.sqadto[0] = (unsigned short )0;
sqlstm.sqtdso[0] = (unsigned short )0;
sqlstm.sqhstv[1] = ( void *)&l_row2;
sqlstm.sqhstl[1] = (unsigned int )1002;
sqlstm.sqhsts[1] = ( int )0;
sqlstm.sqindv[1] = ( void *)0;
sqlstm.sqinds[1] = ( int )0;
sqlstm.sqharm[1] = (unsigned int )0;
sqlstm.sqadto[1] = (unsigned short )0;
sqlstm.sqtdso[1] = (unsigned short )0;
sqlstm.sqphsv = sqlstm.sqhstv;
sqlstm.sqphsl = sqlstm.sqhstl;
sqlstm.sqphss = sqlstm.sqhsts;
sqlstm.sqpind = sqlstm.sqindv;
sqlstm.sqpins = sqlstm.sqinds;
sqlstm.sqparm = sqlstm.sqharm;
sqlstm.sqparc = sqlstm.sqharc;
sqlstm.sqpadto = sqlstm.sqadto;
sqlstm.sqptdso = sqlstm.sqtdso;
sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
if (sqlca.sqlcode < 0) goto main_fail;
}
printf("\nRows processed : [%d]."
"\nReturn Code : [%d].\n\n",
sqlca.sqlerrd[2],
sqlca.sqlcode);
/* BULK INSERTS INTO TABLE USING ARRAYS */
l_row1_arr[0] = 3;
STRING_TO_VARCHAR(l_row2_arr[0], "CDE");
l_row1_arr[1] = 4;
STRING_TO_VARCHAR(l_row2_arr[1], "DEF");
l_row1_arr[2] = 5;
STRING_TO_VARCHAR(l_row2_arr[2], "EFG");
l_row1_arr[3] = 6;
STRING_TO_VARCHAR(l_row2_arr[3], "FGH");
l_row1_arr[4] = 7;
STRING_TO_VARCHAR(l_row2_arr[4], "GHI");
/* THIS WILL INSERT ALL 5 ELEMENTS OF THE ARRAY */
/* EXEC SQL
INSERT INTO A(ROW1, ROW2)
VALUES (:l_row1_arr, :l_row2_arr); */
{
struct sqlexd sqlstm;
sqlstm.sqlvsn = 10;
sqlstm.arrsiz = 4;
sqlstm.sqladtp = &sqladt;
sqlstm.sqltdsp = &sqltds;
sqlstm.stmt = "insert into A(ROW1,ROW2) values (:b0,:b1)";
sqlstm.iters = (unsigned int )5;
sqlstm.offset = (unsigned int )184;
sqlstm.cud = sqlcud0;
sqlstm.sqlest = (unsigned char *)&sqlca;
sqlstm.sqlety = (unsigned short)0;
sqlstm.sqhstv[0] = ( void *)l_row1_arr;
sqlstm.sqhstl[0] = (unsigned int )4;
sqlstm.sqhsts[0] = ( int )4;
sqlstm.sqindv[0] = ( void *)0;
sqlstm.sqinds[0] = ( int )0;
sqlstm.sqharm[0] = (unsigned int )0;
sqlstm.sqharc[0] = (unsigned int *)0;
sqlstm.sqadto[0] = (unsigned short )0;
sqlstm.sqtdso[0] = (unsigned short )0;
sqlstm.sqhstv[1] = ( void *)l_row2_arr;
sqlstm.sqhstl[1] = (unsigned int )102;
sqlstm.sqhsts[1] = ( int )104;
sqlstm.sqindv[1] = ( void *)0;
sqlstm.sqinds[1] = ( int )0;
sqlstm.sqharm[1] = (unsigned int )0;
sqlstm.sqharc[1] = (unsigned int *)0;
sqlstm.sqadto[1] = (unsigned short )0;
sqlstm.sqtdso[1] = (unsigned short )0;
sqlstm.sqphsv = sqlstm.sqhstv;
sqlstm.sqphsl = sqlstm.sqhstl;
sqlstm.sqphss = sqlstm.sqhsts;
sqlstm.sqpind = sqlstm.sqindv;
sqlstm.sqpins = sqlstm.sqinds;
sqlstm.sqparm = sqlstm.sqharm;
sqlstm.sqparc = sqlstm.sqharc;
sqlstm.sqpadto = sqlstm.sqadto;
sqlstm.sqptdso = sqlstm.sqtdso;
sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
if (sqlca.sqlcode < 0) goto main_fail;
}
printf("\nRows processed : [%d]."
"\nReturn Code : [%d].\n\n",
sqlca.sqlerrd[2],
sqlca.sqlcode);
/* EXEC SQL COMMIT; */
{
struct sqlexd sqlstm;
sqlstm.sqlvsn = 10;
sqlstm.arrsiz = 4;
sqlstm.sqladtp = &sqladt;
sqlstm.sqltdsp = &sqltds;
sqlstm.iters = (unsigned int )1;
sqlstm.offset = (unsigned int )207;
sqlstm.cud = sqlcud0;
sqlstm.sqlest = (unsigned char *)&sqlca;
sqlstm.sqlety = (unsigned short)0;
sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
if (sqlca.sqlcode < 0) goto main_fail;
}
l_row1_arr[0] = 8;
STRING_TO_VARCHAR(l_row2_arr[0], "HIJ");
l_row1_arr[1] = 9;
STRING_TO_VARCHAR(l_row2_arr[1], "IJK");
l_row1_arr[2] = 10;
/* THIS WILL ONLY INSERT 3 ROWS INTO THE TABLE, ALTHOUGH THE
* ARRAYS CAN ACCOMODATE MAX OF 5 ELEMENTS */
bulk_insert_ctr = 3;
/* EXEC SQL FOR :bulk_insert_ctr
INSERT INTO A(ROW1, ROW2)
VALUES (:l_row1_arr, :l_row2_arr); */
{
struct sqlexd sqlstm;
sqlstm.sqlvsn = 10;
sqlstm.arrsiz = 4;
sqlstm.sqladtp = &sqladt;
sqlstm.sqltdsp = &sqltds;
sqlstm.stmt = "insert into A(ROW1,ROW2) values (:b1,:b2)";
sqlstm.iters = (unsigned int )bulk_insert_ctr;
sqlstm.offset = (unsigned int )222;
sqlstm.cud = sqlcud0;
sqlstm.sqlest = (unsigned char *)&sqlca;
sqlstm.sqlety = (unsigned short)0;
sqlstm.sqhstv[0] = ( void *)l_row1_arr;
sqlstm.sqhstl[0] = (unsigned int )4;
sqlstm.sqhsts[0] = ( int )4;
sqlstm.sqindv[0] = ( void *)0;
sqlstm.sqinds[0] = ( int )0;
sqlstm.sqharm[0] = (unsigned int )0;
sqlstm.sqharc[0] = (unsigned int *)0;
sqlstm.sqadto[0] = (unsigned short )0;
sqlstm.sqtdso[0] = (unsigned short )0;
sqlstm.sqhstv[1] = ( void *)l_row2_arr;
sqlstm.sqhstl[1] = (unsigned int )102;
sqlstm.sqhsts[1] = ( int )104;
sqlstm.sqindv[1] = ( void *)0;
sqlstm.sqinds[1] = ( int )0;
sqlstm.sqharm[1] = (unsigned int )0;
sqlstm.sqharc[1] = (unsigned int *)0;
sqlstm.sqadto[1] = (unsigned short )0;
sqlstm.sqtdso[1] = (unsigned short )0;
sqlstm.sqphsv = sqlstm.sqhstv;
sqlstm.sqphsl = sqlstm.sqhstl;
sqlstm.sqphss = sqlstm.sqhsts;
sqlstm.sqpind = sqlstm.sqindv;
sqlstm.sqpins = sqlstm.sqinds;
sqlstm.sqparm = sqlstm.sqharm;
sqlstm.sqparc = sqlstm.sqharc;
sqlstm.sqpadto = sqlstm.sqadto;
sqlstm.sqptdso = sqlstm.sqtdso;
sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
if (sqlca.sqlcode < 0) goto main_fail;
}
printf("\nRows processed : [%d]."
"\nReturn Code : [%d].\n\n",
sqlca.sqlerrd[2],
sqlca.sqlcode);
/* The USUAL idea with these bulk inserts is to do something like this
*
* bulk_insert_ctr = 0;
*
* while(<say_reading_something_from_a_file>)
* {
* if(bulk_insert_ctr >= MAX_ARRAY_SIZE_WHICH_WE_HAVE)
* {
* EXEC SQL
* INSERT INTO <SOMETHING> (COL1, COL2, ....)
* VALUES (:l_col1_array, :l_col2_array, .....);
*
* EXEC SQL COMMIT;
*
* bulk_insert_ctr = 0;
*
* }
*
* >> KEEP FILLING THE ARRAYS TILL WE REACH THE LIMIT OF
* >> MAX_ARRAY_SIZE_WHICH_WE_HAVE
*
* l_col1_array[bulk_insert_ctr] = <something>;
* STRING_TO_VARCHAR(l_col2_arr[bulk_insert_ctr], "<something>");
*
* bulk_insert_ctr++;
*
* }//while loop
*
* >> HERE DO INSERTS FOR ANY RESIDUAL DATA THAT MIGHT HAVE
* >> ACCUMULATED INTO OUR LOCAL ARRAYS.
*
* >> NOTICE THE USE OF "FOR :bulk_insert_ctr" HERE
*
* EXEC SQL FOR :bulk_insert_ctr
* INSERT INTO <SOMETHING> (COL1, COL2, ....)
* VALUES (:l_col1_array, :l_col2_array, .....);
*
* EXEC SQL COMMIT;
*
* bulk_insert_ctr = 0;
*
*
*
*
*
* ALSO NOTE THAT IF WE WISH TO INSERT A CONSTANT VALUE (say APPL_TOP_ID,
* which is determined at run-time), WE CANNOT USE A SINGLE VARIABLE LIKE
* l_appL_top_id AND USE IT IN THE BULK INSERT!
*
* EVEN THIS NEEDS TO BE AN ARRAY l_appl_top_id[MAX_ARRAY_SIZE], EVENTHOUGH
* THIS WOULD MEANS DUPLICATION OF APPL_TOP_ID IN ALL THE ARRAY ELEMENTS!
*
* NOTE THAT YOU CAN ALWAYS USE SOMETHING LIKE '1' OR SYSDATE THOUGH, THE
* ABOVE RESTRICTION IS ONLY FOR A RUN_TIME VARIABLE THAT REMAINS SAME
* FOR ALL THE INSERTS....
*
*/
/* END : STATIC SQL */
/* -------------------------------------------------------------------------- */
/* START : CALLING A PL/SQL PROCEDURE */
STRING_TO_VARCHAR(l_owner, "APPS");
STRING_TO_VARCHAR(l_table_name, "A");
STRING_TO_VARCHAR(exec_stmt,"");
/* BUILD UP THE SQL STATEMENT */
strcat(exec_stmt.arr, "\nBEGIN");
strcat(exec_stmt.arr, "\nFND_STATS.GATHER_TABLE_STATS");
strcat(exec_stmt.arr, "\n(");
strcat(exec_stmt.arr, "\n:owner, :tab_name");
strcat(exec_stmt.arr, "\n);");
strcat(exec_stmt.arr, "\nEND;");
SET_LENGTH(exec_stmt);
/* EXEC SQL PREPARE S1 FROM :exec_stmt; */
{
struct sqlexd sqlstm;
sqlstm.sqlvsn = 10;
sqlstm.arrsiz = 4;
sqlstm.sqladtp = &sqladt;
sqlstm.sqltdsp = &sqltds;
sqlstm.stmt = "";
sqlstm.iters = (unsigned int )1;
sqlstm.offset = (unsigned int )245;
sqlstm.cud = sqlcud0;
sqlstm.sqlest = (unsigned char *)&sqlca;
sqlstm.sqlety = (unsigned short)0;
sqlstm.sqhstv[0] = ( void *)&exec_stmt;
sqlstm.sqhstl[0] = (unsigned int )1002;
sqlstm.sqhsts[0] = ( int )0;
sqlstm.sqindv[0] = ( void *)0;
sqlstm.sqinds[0] = ( int )0;
sqlstm.sqharm[0] = (unsigned int )0;
sqlstm.sqadto[0] = (unsigned short )0;
sqlstm.sqtdso[0] = (unsigned short )0;
sqlstm.sqphsv = sqlstm.sqhstv;
sqlstm.sqphsl = sqlstm.sqhstl;
sqlstm.sqphss = sqlstm.sqhsts;
sqlstm.sqpind = sqlstm.sqindv;
sqlstm.sqpins = sqlstm.sqinds;
sqlstm.sqparm = sqlstm.sqharm;
sqlstm.sqparc = sqlstm.sqharc;
sqlstm.sqpadto = sqlstm.sqadto;
sqlstm.sqptdso = sqlstm.sqtdso;
sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
if (sqlca.sqlcode < 0) goto main_fail;
}
printf("\nPrepared : [%s].",
exec_stmt.arr);
/* EXEC SQL EXECUTE S1 USING :l_owner, :l_table_name; */
{
struct sqlexd sqlstm;
sqlstm.sqlvsn = 10;
sqlstm.arrsiz = 4;
sqlstm.sqladtp = &sqladt;
sqlstm.sqltdsp = &sqltds;
sqlstm.stmt = "";
sqlstm.iters = (unsigned int )1;
sqlstm.offset = (unsigned int )264;
sqlstm.cud = sqlcud0;
sqlstm.sqlest = (unsigned char *)&sqlca;
sqlstm.sqlety = (unsigned short)0;
sqlstm.sqhstv[0] = ( void *)&l_owner;
sqlstm.sqhstl[0] = (unsigned int )32;
sqlstm.sqhsts[0] = ( int )0;
sqlstm.sqindv[0] = ( void *)0;
sqlstm.sqinds[0] = ( int )0;
sqlstm.sqharm[0] = (unsigned int )0;
sqlstm.sqadto[0] = (unsigned short )0;
sqlstm.sqtdso[0] = (unsigned short )0;
sqlstm.sqhstv[1] = ( void *)&l_table_name;
sqlstm.sqhstl[1] = (unsigned int )32;
sqlstm.sqhsts[1] = ( int )0;
sqlstm.sqindv[1] = ( void *)0;
sqlstm.sqinds[1] = ( int )0;
sqlstm.sqharm[1] = (unsigned int )0;
sqlstm.sqadto[1] = (unsigned short )0;
sqlstm.sqtdso[1] = (unsigned short )0;
sqlstm.sqphsv = sqlstm.sqhstv;
sqlstm.sqphsl = sqlstm.sqhstl;
sqlstm.sqphss = sqlstm.sqhsts;
sqlstm.sqpind = sqlstm.sqindv;
sqlstm.sqpins = sqlstm.sqinds;
sqlstm.sqparm = sqlstm.sqharm;
sqlstm.sqparc = sqlstm.sqharc;
sqlstm.sqpadto = sqlstm.sqadto;
sqlstm.sqptdso = sqlstm.sqtdso;
sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
if (sqlca.sqlcode < 0) goto main_fail;
}
printf("\nStatement : [%s]."
"\nRows processed : [%d]."
"\nReturn Code : [%d].\n\n",
exec_stmt.arr,
sqlca.sqlerrd[2],
sqlca.sqlcode);
/* END : CALLING A PL/SQL PROCEDURE */
/* ------------------------------------------------------------------------- */
/* START : CURSORS */
printf("\n SPOOLING THE DATA IN THE TABLE\n");
printf("\n----------------------------------------------\n");
printf("ROW1 ROW2");
printf("\n----------------------------------------------\n");
STRING_TO_VARCHAR(exec_stmt,"");
sprintf(exec_stmt.arr, "SELECT ROW1, ROW2 FROM A");
SET_LENGTH(exec_stmt);
/* EXEC SQL PREPARE S1 FROM :exec_stmt; */
{
struct sqlexd sqlstm;
sqlstm.sqlvsn = 10;
sqlstm.arrsiz = 4;
sqlstm.sqladtp = &sqladt;
sqlstm.sqltdsp = &sqltds;
sqlstm.stmt = "";
sqlstm.iters = (unsigned int )1;
sqlstm.offset = (unsigned int )287;
sqlstm.cud = sqlcud0;
sqlstm.sqlest = (unsigned char *)&sqlca;
sqlstm.sqlety = (unsigned short)0;
sqlstm.sqhstv[0] = ( void *)&exec_stmt;
sqlstm.sqhstl[0] = (unsigned int )1002;
sqlstm.sqhsts[0] = ( int )0;
sqlstm.sqindv[0] = ( void *)0;
sqlstm.sqinds[0] = ( int )0;
sqlstm.sqharm[0] = (unsigned int )0;
sqlstm.sqadto[0] = (unsigned short )0;
sqlstm.sqtdso[0] = (unsigned short )0;
sqlstm.sqphsv = sqlstm.sqhstv;
sqlstm.sqphsl = sqlstm.sqhstl;
sqlstm.sqphss = sqlstm.sqhsts;
sqlstm.sqpind = sqlstm.sqindv;
sqlstm.sqpins = sqlstm.sqinds;
sqlstm.sqparm = sqlstm.sqharm;
sqlstm.sqparc = sqlstm.sqharc;
sqlstm.sqpadto = sqlstm.sqadto;
sqlstm.sqptdso = sqlstm.sqtdso;
sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
if (sqlca.sqlcode < 0) goto main_fail;
}
/* EXEC SQL DECLARE mycursor CURSOR FOR S1; */
/* EXEC SQL OPEN mycursor; */
{
struct sqlexd sqlstm;
sqlstm.sqlvsn = 10;
sqlstm.arrsiz = 4;
sqlstm.sqladtp = &sqladt;
sqlstm.sqltdsp = &sqltds;
sqlstm.stmt = "";
sqlstm.iters = (unsigned int )1;
sqlstm.offset = (unsigned int )306;
sqlstm.cud = sqlcud0;
sqlstm.sqlest = (unsigned char *)&sqlca;
sqlstm.sqlety = (unsigned short)0;
sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
if (sqlca.sqlcode < 0) goto main_fail;
}
while(1)
{
/* Fetch 5 rows at a time */
/* EXEC SQL FETCH mycursor
INTO :l_row1_arr, :l_row2_arr; */
{
struct sqlexd sqlstm;
sqlstm.sqlvsn = 10;
sqlstm.arrsiz = 4;
sqlstm.sqladtp = &sqladt;
sqlstm.sqltdsp = &sqltds;
sqlstm.iters = (unsigned int )5;
sqlstm.offset = (unsigned int )321;
sqlstm.cud = sqlcud0;
sqlstm.sqlest = (unsigned char *)&sqlca;
sqlstm.sqlety = (unsigned short)0;
sqlstm.sqhstv[0] = ( void *)l_row1_arr;
sqlstm.sqhstl[0] = (unsigned int )4;
sqlstm.sqhsts[0] = ( int )4;
sqlstm.sqindv[0] = ( void *)0;
sqlstm.sqinds[0] = ( int )0;
sqlstm.sqharm[0] = (unsigned int )0;
sqlstm.sqharc[0] = (unsigned int *)0;
sqlstm.sqadto[0] = (unsigned short )0;
sqlstm.sqtdso[0] = (unsigned short )0;
sqlstm.sqhstv[1] = ( void *)l_row2_arr;
sqlstm.sqhstl[1] = (unsigned int )102;
sqlstm.sqhsts[1] = ( int )104;
sqlstm.sqindv[1] = ( void *)0;
sqlstm.sqinds[1] = ( int )0;
sqlstm.sqharm[1] = (unsigned int )0;
sqlstm.sqharc[1] = (unsigned int *)0;
sqlstm.sqadto[1] = (unsigned short )0;
sqlstm.sqtdso[1] = (unsigned short )0;
sqlstm.sqphsv = sqlstm.sqhstv;
sqlstm.sqphsl = sqlstm.sqhstl;
sqlstm.sqphss = sqlstm.sqhsts;
sqlstm.sqpind = sqlstm.sqindv;
sqlstm.sqpins = sqlstm.sqinds;
sqlstm.sqparm = sqlstm.sqharm;
sqlstm.sqparc = sqlstm.sqharc;
sqlstm.sqpadto = sqlstm.sqadto;
sqlstm.sqptdso = sqlstm.sqtdso;
sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
if (sqlca.sqlcode < 0) goto main_fail;
}
rowsfetched = sqlca.sqlerrd[2] - numtab;
totalrows_fetched = sqlca.sqlerrd[2];
numtab = sqlca.sqlerrd[2];
for(i=0; i<rowsfetched; i++)
{
NULL_TERM(l_row2_arr[i]);
printf("\n[%d] [%s]\n", l_row1_arr[i], l_row2_arr[i].arr);
}
if(sqlca.sqlcode == 1403)break;
}
/* EXEC SQL CLOSE mycursor; */
{
struct sqlexd sqlstm;
sqlstm.sqlvsn = 10;
sqlstm.arrsiz = 4;
sqlstm.sqladtp = &sqladt;
sqlstm.sqltdsp = &sqltds;
sqlstm.iters = (unsigned int )1;
sqlstm.offset = (unsigned int )344;
sqlstm.cud = sqlcud0;
sqlstm.sqlest = (unsigned char *)&sqlca;
sqlstm.sqlety = (unsigned short)0;
sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
if (sqlca.sqlcode < 0) goto main_fail;
}
printf("\n----------------------------------------------\n");
/* END : CURSORS */
/* ------------------------------------------------------------------------ */
/* START : USING INDICATORS */
/*
*
* EXEC SQL BEGIN DECLARE SECTION;
* varchar l_ret_cd[4];
* short l_ret_cd_ind = 0;
* EXEC SQL END DECLARE SECTION;
*
* EXEC SQL EXECUTE S1 USING :l_rlse_id, :l_at_id, :l_ret_cd:l_ret_cd_ind;
*
* if (l_ret_cd_ind == -1)
* STOV(l_ret_cd, "");
*
* nullterm(l_ret_cd);
*
* if (!strcmp((char *)l_ret_cd.arr, "AI"))
*
*
*
* THE SAME CAN BE USED WHILE INSERTING VALUES INTO TABLES
*/
/*
* EXEC SQL BEGIN DECLARE SECTION;
* VARCHAR sql_statemt[400];
* VARCHAR v_mode[200];
* short v_ind_mode;
* EXEC SQL END DECLARE SECTION;
*
* STRING_TO_VARCHAR(sql_statemt, "");
*
* strcat((char *)sql_statemt.arr, "\nBegin");
* strcat((char *)sql_statemt.arr,"\n:p_no_of_rep_ctr:=");
* strcat((char *)sql_statemt.arr,"\nFND_APPS_MODE_UTIL.");
* strcat((char *)sql_statemt.arr,"GET_CURRENT_MODE;");
* strcat((char *)sql_statemt.arr, "\nEnd;");
* setlen(sql_statemt);
*
* EXEC SQL PREPARE S1 FROM
* :sql_statemt;
*
* EXEC SQL EXECUTE S1 USING
* :v_mode:v_ind_mode;
*
* nullterm(v_mode);
*
*/
/* END : USING INDICATORS */
/* ------------------------------------------------------------------------- */
/* Commiting, disconencting, rolbacking ...
*
* EXEC SQL COMMIT WORK;
*
* EXEC SQL COMMIT WORK RELEASE;
*
* EXEC SQL ROLLBACK WORK;
*
* EXEC SQL ROLLBACK WORK RELEASE;
*
*/
/* EXEC SQL COMMIT WORK RELEASE; */
{
struct sqlexd sqlstm;
sqlstm.sqlvsn = 10;
sqlstm.arrsiz = 4;
sqlstm.sqladtp = &sqladt;
sqlstm.sqltdsp = &sqltds;
sqlstm.iters = (unsigned int )1;
sqlstm.offset = (unsigned int )359;
sqlstm.cud = sqlcud0;
sqlstm.sqlest = (unsigned char *)&sqlca;
sqlstm.sqlety = (unsigned short)0;
sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
if (sqlca.sqlcode < 0) goto main_fail;
}
/* -------------------------------------------------------------------- */
/* START : IMPORTANT OPTIONS OR CODE SNIPPETS */
/*
* EXEC ORACLE OPTION (HOLD_CURSOR=YES);
*
*
*
* EXEC SQL
* SELECT 'X'
* INTO :l_dummy
* FROM AD_PATCH_RUN_BUG_ACTIONS
* WHERE PATCH_RUN_BUG_ID = :l_patch_run_bug_id
* AND FILE_ID = :l_file_id
* AND COMMON_ACTION_ID = :l_com_act_id;
*
* if (sqlca.sqlcode == 0)
* {
* *is_a_dup = TRUE;
* return TRUE;
* }
*
*
*
*
*
* EXEC SQL LOCK TABLE IN EXCLUSIVE MODE NOWAIT;
*
*
*
*
*
*
*
* EXEC SQL DECLARE C_PTCH_DRVR CURSOR FOR
* SELECT
* APPLIED_PATCH_ID, PATCH_DRIVER_ID
* FROM
* AD_PATCH_DRIVERS
* WHERE DRIVER_FILE_NAME = :v_driverfile_name
* AND NVL(DRIVER_TYPE_C_FLAG, 'N') = NVL(:v_driver_type_c, 'N')
* AND NVL(DRIVER_TYPE_D_FLAG, 'N') = NVL(:v_driver_type_d, 'N')
* AND NVL(DRIVER_TYPE_G_FLAG, 'N') = NVL(:v_driver_type_g, 'N')
* AND PLATFORM = :v_platform
* AND PLATFORM_VERSION = :v_platform_version
* AND FILE_SIZE = :v_file_size
* AND FILE_CONTENTS_CHECKSUM = :v_check_sum;
*
*
*
*/
/* END : IMPORTANT OPTIONS OR CODE SNIPPETS */
/* -------------------------------------------------------------------- */
return(0);
main_fail:
if(sqlca.sqlcode == -942)
{
goto continue1;
}
else if (sqlca.sqlcode != 0 )
{
msgbufsize = 512;
sqlglm(errmsgbuf, &msgbufsize, &msglength);
errmsgbuf[(msglength < msgbufsize)? msglength : msgbufsize] = '\0';
printf("\nAn error occurred\n\n"
"Code : [%d]\n"
"Description : [%s]\n\n",
sqlca.sqlcode,
errmsgbuf);
}
return(1);
}
This is a sample on how to compile and link a ProC file
comp_it: Starting on Fri Dec 10 07:43:57 PST 2004
Compiling Product C files ...
===============================================================================
++++ Processing file ProC.opc...
proc include=. include=/local/db/8.0.6/precomp/public include=/addev/ad/11.5/include
include=/fnddev/fnd/11.5/include include=/appldev/tools/6.0.8/include include=/appldev/oracle/8.0.6/include
include=/appldev/oracle/8.0.6/oracore3/public include=/appldev/oracle/8.0.6/oracore3/include
include=/appldev/oracle/8.0.6/nlsrtl3/include include=/appldev/oracle/8.0.6/rdbms/public
include=/appldev/oracle/8.0.6/rdbms/include include=/appldev/oracle/8.0.6/network/include
include=/appldev/oracle/8.0.6/otrace/public define=PROC_KLUDGE ireclen=161 dbms=v8 unsafe_null=yes mode=oracle
release_cursor=no maxopencursors=100 hold_cursor=yes char_map=varchar2 parse=partial sqlcheck=syntax
iname=ProC.opc
Pro*C/C++: Release 8.0.6.3.0 - Production on Fri Dec 10 07:43:57 2004
(c) Copyright 1999 Oracle Corporation. All rights reserved.
System default option values taken from: /local/db/8.0.6/precomp/admin/pcscfg.cfg
cc -g -I. -I/addev/ad/11.5/include -I/fnddev/fnd/11.5/include -I/appldev/tools/6.0.8/forms60/pub
-I/appldev/tools/6.0.8/include/forms/60/inc/ic -I/appldev/tools/6.0.8/include/forms/60/inc/if
-I/appldev/tools/6.0.8/include/forms/60/inc/sosd -I/appldev/tools/6.0.8/include/forms/60/inc/tk
-I/appldev/tools/6.0.8/include/forms/60/inc/tk/sosd -I/appldev/tools/6.0.8/include/forms/60/inc/ut
-I/appldev/tools/6.0.8/include/forms/60/inc/uat -I/appldev/tools/6.0.8/include/forms/60/inc/mm
-I/appldev/tools/6.0.8/reports60/pub -I/appldev/tools/6.0.8/include/forms/60/inc/d2f
-I/local/db/8.0.6/precomp/public -I/appldev/oracle/8.0.6/oracore3/public -I/appldev/oracle/8.0.6/oracore3/include
-I/appldev/oracle/8.0.6/nlsrtl3/include -I/appldev/oracle/8.0.6/rdbms/public -I/appldev/oracle/8.0.6/rdbms/include
-I/appldev/oracle/8.0.6/network/include -I/appldev/oracle/8.0.6/otrace/public
-I/appldev/oracle/8.0.6/precomp/include -I/appldev/oracle/8.0.6/network/public -DDEBUG -DLINUX -Dlinux
-DNLS_ASIA -D_GNU_SOURCE -c ProC.c
touch ProC.t
rm -f ProC.lis
===============================================================================
Done compiling Product C files
+++ Not moving product object modules into product lib directory.
comp_it: Done on Fri Dec 10 07:43:58 PST 2004
+ gcc -g -L/local/db/8.0.6/lib -L/local/db/8.0.6/lib/stubs9iR2 -ldl -o myexe ProC.o
/addev/ad/11.5/lib/libad.a /fnddev/fnd/11.5/lib/libfnd.a /local/db/8.0.6/lib/libsql.a
/local/db/8.0.6/lib/nautab.o /local/db/8.0.6/lib/naeet.o /local/db/8.0.6/lib/naect.o
/local/db/8.0.6/lib/naedhs.o /local/db/8.0.6/lib/libnetv2.a /local/db/8.0.6/lib/libnttcp.a
/local/db/8.0.6/lib/libnetwork.a /local/db/8.0.6/lib/libncr.a /local/db/8.0.6/lib/libclient.a
/local/db/8.0.6/lib/libvsn.a /local/db/8.0.6/lib/libcommon.a /local/db/8.0.6/lib/libgeneric.a
/local/db/8.0.6/lib/libmm.a /local/db/8.0.6/lib/libnlsrtl3.a /local/db/8.0.6/lib/libcore4.a
/local/db/8.0.6/lib/libnlsrtl3.a /local/db/8.0.6/lib/libcore4.a /local/db/8.0.6/lib/libnlsrtl3.a
/local/db/8.0.6/lib/libnetv2.a /local/db/8.0.6/lib/libnttcp.a /local/db/8.0.6/lib/libnetwork.a
/local/db/8.0.6/lib/libncr.a /local/db/8.0.6/lib/libclient.a /local/db/8.0.6/lib/libvsn.a
/local/db/8.0.6/lib/libcommon.a /local/db/8.0.6/lib/libgeneric.a /local/db/8.0.6/lib/libepc.a
/local/db/8.0.6/lib/libnlsrtl3.a /local/db/8.0.6/lib/libcore4.a /local/db/8.0.6/lib/libnlsrtl3.a
/local/db/8.0.6/lib/libcore4.a /local/db/8.0.6/lib/libnlsrtl3.a /local/db/8.0.6/lib/libclient.a
/local/db/8.0.6/lib/libvsn.a /local/db/8.0.6/lib/libcommon.a /local/db/8.0.6/lib/libgeneric.a
/local/db/8.0.6/lib/libnlsrtl3.a /local/db/8.0.6/lib/libcore4.a /local/db/8.0.6/lib/libnlsrtl3.a
/local/db/8.0.6/lib/libcore4.a /local/db/8.0.6/lib/libnlsrtl3.a -ldl -lpthread -lm
/local/db/8.0.6/rdbms/lib/defopt.o /local/db/8.0.6/rdbms/lib/ssbbded.o
+ chmod 755 myexe
+ set +x
$