Programmer's Guide to the Oracle7 Server Call Interface Go to Product Documentation Library
Library
Go to books for this product
Product
Go to Contents for this book
Contents
Go to Index
Index



Go to previous file in sequence Go to next file in sequence

Sample Programs in C


This appendix contains sample OCI programs written in C and C++. Also included are the header (.h) files used by these sample programs.

These header files and sample programs are available online. The online location of these programs is system dependent. Refer to your Oracle system-specific documentation for additional information.

This appendix contains listings for the following files:


Header Files

All sample programs and sample header files depend on the types that are defined in the oratypes.h file. If you attempt to compile and run the sample programs, make sure that the directories containing oratypes.h and the OCI header files are on the include path for your compiler.

oratypes.h

The following listing shows an example oratypes.h file. This header is system dependent. The example listed is valid only for SunOS C compilers.

/*
  oratypes.h - System-dependent external definitions of Oracle
  types (SunOS version)
  This header file defines C types used by Oracle demonstration
  code, and code samples in documentation (such as the
  _Programmer's Guide to the Oracle Call Interfaces_)
. Porters must modify oratypes.h to reflect the reality of their
  ports
*/
#ifndef ORASTDDEF
# include <stddef.h>
# define ORASTDDEF
#endif
#ifndef ORALIMITS
# include <limits.h>
# define ORALIMITS
#endif
#ifndef  SX_ORACLE
#define  SX_ORACLE
#define  SX
#define  ORATYPES
#ifndef SS_COMPFLAGS
# include <ss_compflags.h>
#endif
/* define TRUE/FALSE;  defined in some stdio's */
#ifndef TRUE
# define TRUE  1
# define FALSE 0
#endif
#ifdef lint
# ifndef mips
#  define signed
# endif /* mips */
#endif /* lint */
#ifdef ENCORE_88K
# ifndef signed
#  define signed
# endif /* signed */
#endif /* ENCORE_88K */
#if defined(SYSV_386) || defined(SUN_OS)
# ifdef signed
#  undef signed
# endif /* signed */
# define signed
#endif /* SYSV_386 */
#ifndef lint
typedef          int eword;    /* use where sign not important */
typedef unsigned int uword;    /* use where unsigned important */
typedef   signed int sword;    /* use where   signed important */
#else
#define eword int
#define uword unsigned int
#define sword signed int
#endif /*LINT */
#define  EWORDMAXVAL  ((eword) INT_MAX)
#define  EWORDMINVAL  ((eword)       0)
#define  UWORDMAXVAL  ((uword)UINT_MAX)
#define  UWORDMINVAL  ((uword)       0)
#define  SWORDMAXVAL  ((sword) INT_MAX)
#define  SWORDMINVAL  ((sword) INT_MIN)
#define  MINEWORDMAXVAL  ((eword)  32767)
#define  MAXEWORDMINVAL  ((eword)      0)
#define  MINUWORDMAXVAL  ((uword)  65535)
#define  MAXUWORDMINVAL  ((uword)      0)
#define  MINSWORDMAXVAL  ((sword)  32767)
#define  MAXSWORDMINVAL  ((sword) -32767)
 
#ifndef lint
# ifdef mips
typedef   signed char  eb1;
# else
typedef          char  eb1;    /* use where sign not important */
# endif /* mips */

typedef unsigned char  ub1;    /* use where unsigned important */
typedef   signed char  sb1;    /* use where   signed important */
#else
#define eb1 char
#define ub1 unsigned char
#define sb1 signed char
#endif /* LINT */
#define EB1MAXVAL ((eb1)SCHAR_MAX)
#define EB1MINVAL ((eb1)        0)
#if defined(mips)        /* mips compilers barf on x[UB1MAXVAL] */
# ifndef lint
#  define UB1MAXVAL (UCHAR_MAX)
# endif
#endif

#ifndef UB1MAXVAL
# ifdef SCO_UNIX
# define UB1MAXVAL (UCHAR_MAX)
# else
# define UB1MAXVAL ((ub1)UCHAR_MAX)
# endif /* SCO_UNIX */
#endif

#define UB1MINVAL ((ub1)        0)
#define SB1MAXVAL ((sb1)SCHAR_MAX)
#define SB1MINVAL ((sb1)SCHAR_MIN)
#define MINEB1MAXVAL ((eb1)  127)
#define MAXEB1MINVAL ((eb1)    0)
#define MINUB1MAXVAL ((ub1)  255)
#define MAXUB1MINVAL ((ub1)    0)
#define MINSB1MAXVAL ((sb1)  127)
#define MAXSB1MINVAL ((sb1) -127)

/* number of bits in a byte */
#define UB1BITS          CHAR_BIT
#define UB1MASK              0xff
/* human readable (printable) characters */
typedef  unsigned char text;
#ifndef lint
typedef          short    eb2;  /* use where sign not important */
typedef unsigned short    ub2;  /* use where unsigned important */
typedef   signed short    sb2;  /* use where   signed important */
#else
#define eb2  short
#define ub2  unsigned short
#define sb2  signed short
#endif /* LINT */
#define EB2MAXVAL ((eb2) SHRT_MAX)
#define EB2MINVAL ((eb2)        0)
#define UB2MAXVAL ((ub2)USHRT_MAX)
#define UB2MINVAL ((ub2)        0)
#define SB2MAXVAL ((sb2) SHRT_MAX)
#define SB2MINVAL ((sb2) SHRT_MIN)
#define MINEB2MAXVAL ((eb2) 32767)
#define MAXEB2MINVAL ((eb2)     0)
#define MINUB2MAXVAL ((ub2) 65535)
#define MAXUB2MINVAL ((ub2)     0)
#define MINSB2MAXVAL ((sb2) 32767)
#define MAXSB2MINVAL ((sb2)-32767)
 
#ifndef lint
typedef          long  eb4;     /* use where sign not important */
typedef unsigned long  ub4;     /* use where unsigned important */
typedef   signed long  sb4;     /* use where   signed important */
#else
#define eb4 long
#define ub4 unsigned long
#define sb4 signed long
#endif /* LINT */
#define EB4MAXVAL ((eb4) LONG_MAX)
#define EB4MINVAL ((eb4)        0)
#define UB4MAXVAL ((ub4)ULONG_MAX)
#define UB4MINVAL ((ub4)        0)
#define SB4MAXVAL ((sb4) LONG_MAX)
#define SB4MINVAL ((sb4) LONG_MIN)
#define MINEB4MAXVAL ((eb4) 2147483647)
#define MAXEB4MINVAL ((eb4)          0)
#define MINUB4MAXVAL ((ub4) 4294967295)
#define MAXUB4MINVAL ((ub4)          0)
#define MINSB4MAXVAL ((sb4) 2147483647)
#define MAXSB4MINVAL ((sb4)-2147483647)
#ifndef lint
typedef unsigned long  ubig_ora;             /* use where unsigned important */
typedef   signed long  sbig_ora;             /* use where   signed important */
#else
#define ubig_ora unsigned long
#define sbig_ora signed long
#endif /* LINT */
#define UBIG_ORAMAXVAL ((ubig_ora)ULONG_MAX)
#define UBIG_ORAMINVAL ((ubig_ora)        0)
#define SBIG_ORAMAXVAL ((sbig_ora) LONG_MAX)
#define SBIG_ORAMINVAL ((sbig_ora) LONG_MIN)
#define MINUBIG_ORAMAXVAL ((ubig_ora) 4294967295)
#define MAXUBIG_ORAMINVAL ((ubig_ora)          0)
#define MINSBIG_ORAMAXVAL ((sbig_ora) 2147483647)
#define MAXSBIG_ORAMINVAL ((sbig_ora)-2147483647)
/* Use CONST as replacement for the ANSI type qualifier 'const'.*/
#undef CONST
#ifdef _olint
# define CONST const
#else
#if defined(PMAX) && defined(__STDC__)
#   define CONST const
#else
# ifdef M88OPEN
#  define CONST const
# else /* M88OPEN */
# define CONST
# endif /* M88OPEN */
#endif /* PMAX and !ULTRIX_MLS */
#endif /* _olint */
/*
** lgenfp_t, a generic function pointer type.  (It's too bad
** that a level of indirection is hidden, as with the dearly
** departed ptr_t, but typedef'ing a function isn't portable.)
*/

typedef void (*lgenfp_t)(/*_ void _*/);
/* dvoid: base type for pointer to arbitrary block of memory    **
** use as "dvoid *"; in ansi environments, dvoid should be void **
** If your compiler doesn't support void *, dvoid * should match**
** the return type from memcpy()/memset(), i.e. probably char * **
** VMS defines (as opposed to typedefing) dvoid when linting to **
** allow dvoid* to match void* while being strict about other   **
** typedefs (i.e. short not matching ub2).                      */
#ifdef lint
# define dvoid void
#else
# ifdef UTS2
#  define dvoid char
# else
# define dvoid void
# endif /* UTS2 */
#endif /* lint */
/* type boolean, for TRUE/FALSE function local variables and
** parameters; defined as int for efficient processing and to
** match the natural type for C boolean expressions.  Do not use
** where space efficiency is important.
*/
#ifndef ORASYSTYPES
# include <sys/types.h>
# define ORASYSTYPES
#endif /* !ORAUSRINCLUDESYSTYPES */
#define boolean int
/* SIZE_TMAXVAL is the largest amount of memory that the 
** current platform is capable of allocating in one single block.
** The constant MINSIZE_TMAXVAL is the largest allocation across
** all platforms.
*/
#ifdef sparc
# define SIZE_TMAXVAL SB4MAXVAL  /* This case applies for sun4 */
#else
# define SIZE_TMAXVAL UB4MAXVAL  /* This case applies for others */
#endif /* sparc */
#define MINSIZE_TMAXVAL (size_t)65535
#endif /* SX_ORACLE */
/*

ocidfn.h

/*
 *  ocidfn.h
 *  Common header file for OCI C sample programs.
 *  This header declares the cursor and logon data area structure.
 *  The types used are defined in <oratypes.h>.
 */
#ifndef OCIDFN
#define OCIDFN
#include <oratypes.h>

/* The cda_head struct is strictly PRIVATE.  It is used
   internally only. Do not use this struct in OCI programs. */
struct cda_head {
    sb2          v2_rc;
    ub2          ft;
    ub4          rpc;
    ub2          peo;
    ub1          fc;
    ub1          rcs1;
    ub2          rc;
    ub1          wrn;
    ub1          rcs2;
    sword        rcs3;
    struct {
        struct {
           ub4    rcs4;
           ub2    rcs5;
           ub1    rcs6;
        } rd;
        ub4    rcs7;
        ub2    rcs8;
    } rid;
    sword        ose;
    ub1           chk;
    dvoid        *rcsp;
};
# define CDA_SIZE 64
/* the real CDA, padded to CDA_SIZE bytes in size */
struct cda_def {
    sb2          v2_rc;                       /* V2 return code */
    ub2          ft;                       /* SQL function type */
    ub4          rpc;                   /* rows processed count */
    ub2          peo;                     /* parse error offset */
    ub1          fc;                       /* OCI function code */
    ub1          rcs1;                           /* filler area */
    ub2          rc;                          /* V7 return code */
    ub1          wrn;                          /* warning flags */
    ub1          rcs2;                              /* reserved */
    sword        rcs3;                              /* reserved */
    struct {                                 /* rowid structure */
        struct {
           ub4    rcs4;
           ub2    rcs5;
           ub1    rcs6;
        } rd;
        ub4    rcs7;
        ub2    rcs8;
    } rid;
    sword        ose;                    /* OSD dependent error */
    ub1          chk;
    dvoid        *rcsp;             /* pointer to reserved area */
    ub1          rcs9[CDA_SIZE - sizeof (struct cda_head)];        /* filler */
};
typedef struct cda_def Cda_Def;
/* the logon data area (LDA)
   is the same shape as the CDA */
typedef struct cda_def Lda_Def;

/* OCI Environment Modes for opinit call */
#define OCI_EV_DEF 0     /* default single-threaded environment */
#define OCI_EV_TSF 1                 /* thread-safe environment */

/* OCI Logon Modes for olog call */
#define OCI_LM_DEF 0                           /* default login */
#define OCI_LM_NBL 1                      /* non-blocking logon */

/* 
 * since sqllib uses both ocidef and ocidfn the following defines
 * need to be guarded
 */
#ifndef OCI_FLAGS 
#define OCI_FLAGS

/* OCI_*_PIECE defines the piece types that are returned or set */
#define OCI_ONE_PIECE   0    /* there or this is the only piece */
#define OCI_FIRST_PIECE 1           /* the first of many pieces */
#define OCI_NEXT_PIECE  2            /* the next of many pieces */
#define OCI_LAST_PIECE  3      /* the last piece of this column */
#endif

/* input data types */
#define SQLT_CHR  1           /* (ORANET TYPE) character string */
#define SQLT_NUM  2             /* (ORANET TYPE) oracle numeric */
#define SQLT_INT  3                    /* (ORANET TYPE) integer */
#define SQLT_FLT  4      /* (ORANET TYPE) Floating point number */
#define SQLT_STR  5                   /* zero terminated string */
#define SQLT_VNU  6           /* NUM with preceding length byte */
#define SQLT_PDN  7     /* (ORANET TYPE) Packed Decimal Numeric */
#define SQLT_LNG  8                                     /* long */
#define SQLT_VCS  9                /* Variable character string */
#define SQLT_NON  10         /* Null/empty PCC Descriptor entry */
#define SQLT_RID  11                                   /* rowid */
#define SQLT_DAT  12                   /* date in oracle format */
#define SQLT_VBI  15                    /* binary in VCS format */
#define SQLT_BIN  23                     /* binary data(DTYBIN) */
#define SQLT_LBI  24                             /* long binary */
#define SQLT_UIN  68                        /* unsigned integer */
#define SQLT_SLS  91           /* Display sign leading separate */
#define SQLT_LVC  94                     /* Longer longs (char) */
#define SQLT_LVB  95                      /* Longer long binary */ 
#define SQLT_AFC  96                         /* Ansi fixed char */
#define SQLT_AVC  97                           /* Ansi Var char */
#define SQLT_CUR  102                           /* cursor  type */
#define SQLT_LAB  105                             /* label type */
#define SQLT_OSL  106                           /* oslabel type */

#endif  /* OCIDFN */

ocidem.h

/*  ocidem.h
 *  Declares additional functions and data structures
 *  used in the OCI C sample programs.
 */

#include <oratypes.h>

#ifndef OCIDEM
#define OCIDEM

/*  internal/external datatype codes */
#define VARCHAR2_TYPE            1
#define NUMBER_TYPE              2
#define INT_TYPE<T><T>           3
#define FLOAT_TYPE               4
#define STRING_TYPE              5
#define ROWID_TYPE              11
#define DATE_TYPE               12

/*  ORACLE error codes used in demonstration programs */
#define VAR_NOT_IN_LIST       1007
#define NO_DATA_FOUND         1403
#define NULL_VALUE_RETURNED   1405

/*  some SQL and OCI function codes */
#define FT_INSERT                3
#define FT_SELECT                4
#define FT_UPDATE                5
#define FT_DELETE                9

#define FC_OOPEN                14

/*
 *  OCI function code labels,
 *  corresponding to the fc numbers
 *  in the cursor data area.
 */

CONST text  *oci_func_tab[] =  {(text *) "not used",
/* 1-2 */       (text *) "not used", (text *) "OSQL",
/* 3-4 */       (text *) "not used", (text *) "OEXEC, OEXN",
/* 5-6 */       (text *) "not used", (text *) "OBIND",
/* 7-8 */       (text *) "not used", (text *) "ODEFIN",
/* 9-10 */      (text *) "not used", (text *) "ODSRBN",
/* 11-12 */     (text *) "not used", (text *) "OFETCH, OFEN",
/* 13-14 */     (text *) "not used", (text *) "OOPEN",
/* 15-16 */     (text *) "not used", (text *) "OCLOSE",
/* 17-18 */     (text *) "not used", (text *) "not used",
/* 19-20 */     (text *) "not used", (text *) "not used",
/* 21-22 */     (text *) "not used", (text *) "ODSC",
/* 23-24 */     (text *) "not used", (text *) "ONAME",
/* 25-26 */     (text *) "not used", (text *) "OSQL3",
/* 27-28 */     (text *) "not used", (text *) "OBNDRV",
/* 29-30 */     (text *) "not used", (text *) "OBNDRN",
/* 31-32 */     (text *) "not used", (text *) "not used",
/* 33-34 */     (text *) "not used", (text *) "OOPT",
/* 35-36 */     (text *) "not used", (text *) "not used",
/* 37-38 */     (text *) "not used", (text *) "not used",
/* 39-40 */     (text *) "not used", (text *) "not used",
/* 41-42 */     (text *) "not used", (text *) "not used",
/* 43-44 */     (text *) "not used", (text *) "not used",
/* 45-46 */     (text *) "not used", (text *) "not used",
/* 47-48 */     (text *) "not used", (text *) "not used",
/* 49-50 */     (text *) "not used", (text *) "not used",
/* 51-52 */     (text *) "not used", (text *) "OCAN",
/* 53-54 */     (text *) "not used", (text *) "OPARSE",
/* 55-56 */     (text *) "not used", (text *) "OEXFET",
/* 57-58 */     (text *) "not used", (text *) "OFLNG",
/* 59-60 */     (text *) "not used", (text *) "ODESCR",
/* 61-62 */     (text *) "not used", (text *) "OBNDRA"
};

#endif      /* OCIDEM */

ociapr.h

/*
 *  Declare the OCI functions.
 *  Prototype information is included.
 *  Use this header for ANSI C compilers.
 */

#ifndef OCIAPR
#define OCIAPR

#include <oratypes.h>
#include <ocidfn.h>

sword  obindps(struct cda_def *cursor, ub1 opcode, text *sqlvar, 
              sb4 sqlvl, ub1 *pvctx, sb4 progvl, 
              sword ftype, sword scale,
              sb2 *indp, ub2 *alen, ub2 *arcode, 
              sb4 pv_skip, sb4 ind_skip, sb4 alen_skip, sb4 
              rc_skip, ub4 maxsiz, ub4 *cursiz,
              text *fmt, sb4 fmtl, sword fmtt);
sword  obreak(struct cda_def *lda);
sword  ocan  (struct cda_def *cursor);
sword  oclose(struct cda_def *cursor);
sword  ocof  (struct cda_def *lda);
sword  ocom  (struct cda_def *lda);
sword  ocon  (struct cda_def *lda);
sword  odefinps(struct cda_def *cursor, ub1 opcode, sword pos,ub1 
             *bufctx, sb4 bufl, sword ftype, sword scale, 
             sb2 *indp, text *fmt, sb4 fmtl, sword fmtt, 
             ub2 *rlen, ub2 *rcode,
             sb4 pv_skip, sb4 ind_skip, sb4 alen_skip,
             sb4 rc_skip);
sword  odessp(struct cda_def *cursor, text *objnam, size_t onlen,
             ub1 *rsv1, size_t rsv1ln, ub1 *rsv2, size_t rsv2ln,
             ub2 *ovrld, ub2 *pos, ub2 *level, text **argnam,
             ub2 *arnlen, ub2 *dtype, ub1 *defsup, ub1* mode,
             ub4 *dtsiz, sb2 *prec, sb2 *scale, ub1 *radix,
             ub4 *spare, ub4 *arrsiz);
sword  odescr(struct cda_def *cursor, sword pos, sb4 *dbsize,
             sb2 *dbtype, sb1 *cbuf, sb4 *cbufl, sb4 *dsize,
             sb2 *prec, sb2 *scale, sb2 *nullok);
sword  oerhms(struct cda_def *lda, sb2 rcode, text *buf,
             sword bufsiz);
sword  oermsg(sb2 rcode, text *buf);
sword  oexec (struct cda_def *cursor);
sword  oexfet(struct cda_def *cursor, ub4 nrows,
             sword cancel, sword exact);
sword  oexn  (struct cda_def *cursor, sword iters, sword rowoff);
sword  ofen  (struct cda_def *cursor, sword nrows);
sword  ofetch(struct cda_def *cursor);
sword  oflng (struct cda_def *cursor, sword pos, ub1 *buf,
             sb4 bufl, sword dtype, ub4 *retl, sb4 offset);
sword  ogetpi(struct cda_def *cursor, ub1 *piecep, dvoid **ctxpp, 
             ub4 *iterp, ub4 *indexp);
sword  opinit(ub4 mode);
sword  olog  (struct cda_def *lda, ub1* hda,
             text *uid, sword uidl, text *pswd, sword pswdl, 
             text *conn, sword connl, ub4 mode);
sword  ologof(struct cda_def *lda);
sword  oopen (struct cda_def *cursor, struct cda_def *lda,
             text *dbn, sword dbnl, sword arsize,
             text *uid, sword uidl);
sword  oparse(struct cda_def *cursor, text *sqlstm, sb4 sqllen,
             sword defflg, ub4 lngflg);
sword  orol  (struct cda_def *lda);
sword  osetpi(struct cda_def *cursor, ub1 piece, dvoid *bufp,
             ub4 *lenp);
void sqlld2  (struct cda_def *lda, text *cname, sb4 *cnlen);
void sqllda  (struct cda_def *lda);

/* non-blocking functions */
sword onbset (struct cda_def *lda ); 
sword onbtst (struct cda_def *lda ); 
sword onbclr (struct cda_def *lda ); 
sword  oopt  (struct cda_def *cursor, sword rbopt, sword waitopt);

sword  obndra(struct cda_def *cursor, text *sqlvar, sword sqlvl,
             ub1 *progv, sword progvl, sword ftype, sword scale,
             sb2 *indp, ub2 *alen, ub2 *arcode, ub4 maxsiz,
             ub4 *cursiz, text *fmt, sword fmtl, sword fmtt);
sword  obndrn(struct cda_def *cursor, sword sqlvn, ub1 *progv,
             sword progvl, sword ftype, sword scale, sb2 *indp,
             text *fmt, sword fmtl, sword fmtt);
sword  obndrv(struct cda_def *cursor, text *sqlvar, sword sqlvl,
             ub1 *progv, sword progvl, sword ftype, sword scale,
             sb2 *indp, text *fmt, sword fmtl, sword fmtt);
sword  odefin(struct cda_def *cursor, sword pos, ub1 *buf,
             sword bufl, sword ftype, sword scale, sb2 *indp,
             text *fmt, sword fmtl, sword fmtt, ub2 *rlen,
             ub2 *rcode);

/* older calls ; preferred equivalent calls above */
sword  oname (struct cda_def *cursor, sword pos, sb1 *tbuf,
             sb2 *tbufl, sb1 *buf, sb2 *bufl);
sword  orlon (struct cda_def *lda, ub1 *hda, 
             text *uid, sword uidl, text *pswd, sword pswdl, 
             sword audit);
sword  olon  (struct cda_def *lda, text *uid, sword uidl,
             text *pswd, sword pswdl, sword audit);
sword  osql3 (struct cda_def *cda, text *sqlstm, sword sqllen);
sword  odsc  (struct cda_def *cursor, sword pos, sb2 *dbsize,
             sb2 *fsize, sb2 *rcode, sb2 *dtype, sb1 *buf,
             sb2 *bufl, sb2 *dsize);

#endif /* OCIAPR */

ocikpr.h

/*
 *  Declare the OCI functions.
 *  Prototype information is commented out.
 *  Use this header for non-ANSI C compilers.
 *  Note that you will need to include ocidfn.h in the .c files
 *    to get the definition for cda_def.
 */

#ifndef OCIKPR
#define OCIKPR

#include <oratypes.h>

sword obindps( /*_ struct cda_def *cursor, ub1 opcode, text                    *sqlvar, sb4 sqlvl, ub1 *pvctx, sb4 progvl, 
            sword ftype, sword scale,
            sb2 *indp, ub2 *alen, ub2 *arcode, 
            sb4 pv_skip, sb4 ind_skip, sb4 alen_skip, sb4 rc_skip,
            ub4 maxsiz, ub4 *cursiz, text *fmt, sb4 fmtl,
            sword fmtt _*/ );
sword obreak( /*_ struct cda_def *lda _*/ );
sword ocan  ( /*_ struct cda_def *cursor _*/ );
sword oclose( /*_ struct cda_def *cursor _*/ );
sword ocof  ( /*_ struct cda_def *lda _*/ );
sword ocom  ( /*_ struct cda_def *lda _*/ );
sword ocon  ( /*_ struct cda_def *lda _*/ );
sword odefinps( /*_ struct cda_def *cursor, ub1 opcode, sword 
            pos,ub1 *bufctx, sb4 bufl, sword ftype, sword scale, 
            sb2 *indp, text *fmt, sb4 fmtl, sword fmtt, 
            ub2 *rlen, ub2 *rcode,
            sb4 pv_skip, sb4 ind_skip, sb4 alen_skip,
            sb4 rc_skip _*/ );
sword odescr( /*_ struct cda_def *cursor, sword pos, sb4 *dbsize,
            sb2 *dbtype, sb1 *cbuf, sb4 *cbufl, sb4 *dsize,
            sb2 *prec, sb2 *scale, sb2 *nullok _*/ );



sword odessp( /*_ struct cda_def *cursor, text *objnam, size_t
            onlen, ub1 *rsv1, size_t rsv1ln, ub1 *rsv2, size_t 
            rsv2ln, ub2 *ovrld, ub2 *pos, ub2 *level, text
            **argnam, ub2 *arnlen, ub2 *dtype, ub1 *defsup, ub1* 
            mode, ub4 *dtsiz, sb2 *prec, sb2 *scale, ub1 *radix,
            ub4 *spare, ub4 *arrsiz _*/ );
sword oerhms( /*_ struct cda_def *lda, sb2 rcode, text *buf,
                   sword bufsiz _*/ );
sword oermsg( /*_ sb2 rcode, text *buf _*/ );
sword oexec ( /*_ struct cda_def *cursor _*/ );
sword oexfet( /*_ struct cda_def *cursor, ub4 nrows,
                   sword cancel, sword exact _*/ );
sword oexn  ( /*_ struct cda_def *cursor, sword iters, sword 
            rowoff _*/ );
sword ofen  ( /*_ struct cda_def *cursor, sword nrows _*/ );
sword ofetch( /*_ struct cda_def *cursor _*/ );
sword oflng ( /*_ struct cda_def *cursor, sword pos, ub1 *buf,
             sb4 bufl, sword dtype, ub4 *retl, sb4 offset _*/ );
sword ogetpi( /*_ struct cda_def *cursor, ub1 *piecep, dvoid 
             **ctxpp, ub4 *iterp, ub4 *indexp _*/ );
sword opinit( /*_ ub4 mode _*/ );
sword olog  ( /*_ struct cda_def *lda, ub1 *hst, 
             text *uid, sword uidl,
             text *psw, sword pswl, 
             text *conn, sword connl, 
             ub4 mode _*/ );
sword ologof( /*_ struct cda_def *lda _*/ );
sword oopen ( /*_ struct cda_def *cursor, struct cda_def *lda,
             text *dbn, sword dbnl, sword arsize,
             text *uid, sword uidl _*/ );
sword oopt  ( /*_ struct cda_def *cursor, sword rbopt, sword 
             waitopt _*/ );
sword oparse( /*_ struct cda_def *cursor, text *sqlstm, sb4 
             sqllen, sword defflg, ub4 lngflg _*/ );
sword orol  ( /*_ struct cda_def *lda _*/ );
sword osetpi( /*_ struct cda_def *cursor, ub1 piece, dvoid *bufp,               ub4 *lenp _*/ );
void sqlld2  ( /*_ struct cda_def *lda, text *cname,
             sb4 *cnlen _*/ );
void sqllda  ( /*_ struct cda_def *lda _*/ );

/* non-blocking functions */
sword onbset( /*_ struct cda_def *lda _*/ ); 
sword onbtst( /*_ struct cda_def *lda _*/ ); 
sword onbclr( /*_ struct cda_def *lda _*/ ); 



sword obndra( /*_ struct cda_def *cursor, text *sqlvar, sword 
             sqlvl, ub1 *progv, sword progvl, sword ftype, sword  
             scale, sb2 *indp, ub2 *alen, ub2 *arcode, ub4 maxsiz,
             ub4 *cursiz, text *fmt, sword fmtl, sword fmtt _*/ );
sword obndrn( /*_ struct cda_def *cursor, sword sqlvn, ub1 
             *progv, sword progvl, sword ftype, sword scale, sb2 
             *indp, text *fmt, sword fmtl, sword fmtt _*/ );
sword obndrv( /*_ struct cda_def *cursor, text *sqlvar, sword 
             sqlvl, ub1 *progv, sword progvl, sword ftype, sword                scale, sb2 *indp, text *fmt, sword fmtl,
             sword fmtt _*/ );
sword odefin( /*_ struct cda_def *cursor, sword pos, ub1 *buf,
             sword bufl, sword ftype, sword scale, sb2 *indp,
             text *fmt, sword fmtl, sword fmtt, ub2 *rlen, ub2
             *rcode _*/ );

/* older calls ; preferred equivalent calls above */
sword odsc  ( /*_ struct cda_def *cursor, sword pos, sb2 *dbsize,
                   sb2 *fsize, sb2 *rcode, sb2 *dtype, sb1 *buf,
           sb2 *bufl, sb2 *dsize _*/ );
sword oname ( /*_ struct cda_def *cursor, sword pos, sb1 *tbuf,
           sb2 *tbufl, sb1 *buf, sb2 *bufl _*/ );
sword olon  ( /*_ struct cda_def *lda, text *uid, sword uidl,
           text *pswd, sword pswdl, sword audit _*/ );
sword orlon ( /*_ struct cda_def *lda, ub1 *hda, text *uid,
           sword uidl, text *pswd, sword pswdl, sword audit _*/ );
sword osql3 ( /*_ struct cda_def *cda, text *sqlstm,
           sword sqllen _*/ );

#endif  /* OCIKPR */

cdemo6.h

/* Used with cdemo6.cc */

extern "C"
{
#include <string.h>
#include <oratypes.h>
#include <ocidfn.h>
#include <ocidem.h>
}
/* oparse flags */
#define  DEFER_PARSE        1
#define  NATIVE             1
#define  VERSION_7          2
/* Class forward declarations */
class connection;
class cursor;
/*
 * This class represents a connection to ORACLE database.
 *
 * NOTE: This connection class is just given as an example and all   * possible operations on a connection have not been defined.
 */

class connection
{
  friend class cursor;
  public:
    connection() 
      { state = not_connected; memset(hda,'\0', HDA_SIZE); }
    ~connection();
    sword connect(const text *username, const text *password);
    sword disconnect();
    void display_error(FILE* file) const;
  private:
    Lda_Def lda;
    ub1 hda[HDA_SIZE];
    enum conn_state
    {
      not_connected,
      connected
    };
    conn_state state;
};
/*
 * This class represents an ORACLE cursor.
 *
 * NOTE: This cursor class is just given as an example and all 
 *       possible operations on a cursor have not been defined.
 */
class cursor
{
  public:
    cursor() 
      {state = not_opened; conn = (connection *)0; }
    ~cursor();
    sword open(connection *conn_param);
    sword close();
    sword parse(const text *stmt)
      { return (oparse(&cda, (text *)stmt, (sb4)-1, 
                DEFER_PARSE, (ub4) VERSION_7)); }
    /* bind an input variable */
    sword bind_by_position(sword sqlvnum, ub1 *progvar, sword 
                           progvarlen, sword datatype, sword 
                           scale, sb2 *indicator)
      { return (obndrn(&cda, sqlvnum, progvar, progvarlen, 
                           datatype, scale, indicator, (text *)0, 
                           -1, -1)); }
    /* define an output variable */
    sword define_by_position(sword position, ub1 *buf, sword bufl,                             sword datatype, sword scale, sb2 
                           *indicator, ub2 *rlen, ub2 *rcode)
      { return (odefin(&cda, position, buf, bufl, datatype, scale,
                           indicator,(text *)0, -1, -1, rlen, 
                           rcode)); }
    sword describe(sword position, sb4 *dbsize, sb2 *dbtype, sb1 
                           *cbuf, sb4 *cbufl, sb4 *dsize, sb2 
                           *prec, sb2 *scale, sb2 *nullok)
      { return (odescr(&cda, position, dbsize, dbtype, cbuf, 
                cbufl, dsize, prec, scale, nullok)); }
    sword execute()
      { return (oexec(&cda)); }
    sword fetch()
      { return (ofetch(&cda)); }
    sword get_error_code() const
      { return (cda.rc); }
    void display_error( FILE* file) const;
  private:
    Cda_Def cda;
    connection *conn;
    enum cursor_state
    {
      not_opened,
      opened
    };
    cursor_state state;
};
/*
 * Error number macros
 */
#define CONERR_ALRCON -1                   /* already connected */
#define CONERR_NOTCON -2                       /* not connected */
#define CURERR_ALROPN -3              /* cursor is already open */
#define CURERR_NOTOPN -4                /* cursor is not opened */


cdemo1.c

/* 
 *      -- cdemo1.c --
 *  An example program which adds new employee
 *  records to the personnel data base.  Checking
 *  is done to insure the integrity of the data base.
 *  The employee numbers are automatically selected using
 *  the current maximum employee number as the start.
 *  
 *  The program queries the user for data as follows:
 *   
 *  Enter employee name:
 *  Enter employee job:
 *  Enter employee salary:
 *  Enter employee dept:
 *   
 *  The program terminates if return key (CR) is entered
 *  when the employee name is requested.
 *   
 *  If the record is successfully inserted, the following
 *  is printed:
 *   
 *  "ename" added to department "dname" as employee # "empno"
 *
 *  The size of the HDA is defined by the HDA_SIZE constant,
 *  which is declared in ocidem.h to be 256 bytes for 32-
 *  bit architectures and 512 bytes for 64-bit architectures.
 */

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <oratypes.h>

/* LDA and CDA struct declarations */
#include <ocidfn.h>
#ifdef __STDC__
#include <ociapr.h>
#else
#include <ocikpr.h>
#endif

/* demo constants and structs */
#include <ocidem.h>

/* oparse flags */
#define  DEFER_PARSE        1
#define  NATIVE             1
#define  VERSION_7          2
 
text *username = (text *) "SCOTT";
text *password = (text *) "TIGER";

/* Define SQL statements to be used in program. */
text *insert = (text *) "INSERT INTO emp(empno, ename, job, sal, 
    ndeptno)\
    VALUES (:empno, :ename, :job, :sal, :deptno)";
text *seldept = (text *) "SELECT dname FROM dept WHERE deptno = 
    :1";
text *maxemp = (text *) "SELECT NVL(MAX(empno), 0) FROM emp";
text *selemp = (text *) "SELECT ename, job FROM emp";

/* Define an LDA, a HDA,  and two cursors. */
Lda_Def lda;
ub1     hda[HDA_SIZE];
Cda_Def cda1;
Cda_Def cda2;

void err_report();
void myfflush();

main()
{
    sword empno, sal, deptno;
    sword len, len2, rv, dsize, dsize2;
    sb4   enamelen, joblen, deptlen;
    sb2   sal_ind, job_ind;
    sb2   db_type, db2_type;
    sb1   name_buf[20], name2_buf[20];
    text  *cp, *ename, *job, *dept;

/* 
 *  Connect to ORACLE and open two cursors.
 *  Exit on any error.
 */
    if (olog(&lda, hda, username, -1, password, -1,
             (text *) 0, -1, OCI_LM_DEF))
    {
        err_report(&lda);
        exit(EXIT_FAILURE);
    }
    printf("Connected to ORACLE as %s\n", username);

    if (oopen(&cda1, &lda, (text *) 0, -1, -1, (text *) 0, -1))
    {
        err_report(&cda1);
        do_exit(EXIT_FAILURE);
    }

    if (oopen(&cda2, &lda, (text *) 0, -1, -1, (text *) 0, -1))
    {
        err_report(&cda2);
        do_exit(EXIT_FAILURE);
    }

    /* Turn off auto-commit. Default is off, however. */
    if (ocof(&lda))
    {
        err_report(&lda);
        do_exit(EXIT_FAILURE);
    }

    /* Retrieve the current maximum employee number. */
    if (oparse(&cda1, maxemp, (sb4) -1, DEFER_PARSE,
               (ub4) VERSION_7))
    {
        err_report(&cda1);
        do_exit(EXIT_FAILURE);
    }

    if (odefin(&cda1, 1, (ub1 *) &empno, (sword) sizeof(sword),
               (sword) INT_TYPE,
               (sword) -1, (sb2 *) 0, (text *) 0, -1, -1,
               (ub2 *) 0, (ub2 *) 0))
    {
        err_report(&cda1);
        do_exit(EXIT_FAILURE);
    }

    if (oexfet(&cda1, (ub4) 1, FALSE, FALSE))
    {
        if (cda1.rc == NO_DATA_FOUND)
            empno = 10;
        else
        {
            err_report(&cda1);
            do_exit(EXIT_FAILURE);
        }
    }

    /*  Describe the columns in the select-list
        of "selemp" to determine the max length of
        the employee name and job title.
     */
    if (oparse(&cda1, selemp, (sb4) -1, FALSE, VERSION_7))
    {
        err_report(&cda1);
        do_exit(EXIT_FAILURE);
    }

    len = sizeof(name_buf); len2 = sizeof (name2_buf);

    if (odescr(&cda1, 1, &enamelen,
               (sb2 *) &db_type, name_buf, (sb4 *) &len,
               (sb4 *) &dsize, (sb2 *) 0, (sb2 *) 0, (sb2 *) 0) ||
        odescr(&cda1, 2, &joblen,
               (sb2 *) &db_type, name2_buf, (sb4 *) &len2,
               (sb4 *) &dsize2, (sb2 *) 0, (sb2 *) 0, (sb2 *) 0))
    {
        err_report(&cda1);
        do_exit(EXIT_FAILURE);
    }

    /* Parse the INSERT statement. */
    if (oparse(&cda1, insert, (sb4) -1, FALSE, (ub4) VERSION_7))
    {
        err_report(&cda1);
        do_exit(EXIT_FAILURE);
    }

    /* Parse the SELDEPT statement. */
    if (oparse(&cda2, seldept, (sb4) -1, FALSE, (ub4) VERSION_7))
    {
        err_report(&cda2);
        do_exit(EXIT_FAILURE);
    }

    /*  Allocate output buffers. Allow for \n and '\0'. */
    ename = (text *) malloc((int) enamelen + 2);
    job   = (text *) malloc((int) joblen + 2);

    /*  Bind the placeholders in the INSERT statement. */
    if (obndrv(&cda1, (text *) ":ENAME", -1, (ub1 *) ename,
               enamelen+1, STRING_TYPE, -1, (sb2 *) 0,
               (text *) 0, -1, -1) ||
        obndrv(&cda1, (text *) ":JOB", -1, (ub1 *) job, joblen+1,
               STRING_TYPE, -1, &job_ind, (text *) 0, -1, -1) ||
        obndrv(&cda1, (text *) ":SAL", -1, (ub1 *) &sal, 
               (sword)sizeof (sal),
               INT_TYPE, -1, &sal_ind, (text *) 0, -1, -1) ||
        obndrv(&cda1, (text *) ":DEPTNO",-1, (ub1 *) &deptno,
               (sword) sizeof (deptno), INT_TYPE, -1,
               (sb2 *) 0, (text *) 0, -1, -1) ||
        obndrv(&cda1, (text *) ":EMPNO", -1, (ub1 *) &empno,
               (sword) sizeof (empno), INT_TYPE, -1,
               (sb2 *) 0, (text *) 0, -1, -1))
    {
        err_report(&cda1);
        do_exit(EXIT_FAILURE);
    }

    /*  Bind the placeholder in the "seldept" statement. */
    if (obndrn(&cda2,
               1,
               (ub1 *) &deptno,
               (sword) sizeof(deptno),
               INT_TYPE,
               -1,
               (sb2 *) 0,
               (text *) 0,
               -1,
               -1))
    {
        err_report(&cda2);
        do_exit(EXIT_FAILURE);
    }  

    /*  Describe the select-list field "dname". */
    len = sizeof (name_buf);
    if (odescr(&cda2, 1, (sb4 *) &deptlen, &db_type,
               name_buf, (sb4 *) &len, (sb4 *) &dsize, (sb2 *) 0,
               (sb2 *) 0, (sb2 *) 0))
    {
        err_report(&cda2);
        do_exit(EXIT_FAILURE);
    }

/*  Allocate the dept buffer now that you have length. */
    dept = (text *) malloc((int) deptlen + 1);






    /*  Define the output variable for the select-list. */
    if (odefin(&cda2,
               1,
               (ub1 *) dept,
               deptlen+1,
               STRING_TYPE,
               -1,
               (sb2 *) 0,
               (text *) 0,
               -1,
               -1,
               (ub2 *) 0,
               (ub2 *) 0))
    {
        err_report(&cda2);
        do_exit(EXIT_FAILURE);
    }
    for (;;)
    {
        /* Prompt for employee name.  Break on no name. */
        printf("\nEnter employee name (or CR to EXIT): ");
        fgets((char *) ename, (int) enamelen+1, stdin);
        cp = (text *) strchr((char *) ename, '\n');
        if (cp == ename)
        {
            printf("Exiting... ");
            do_exit(EXIT_SUCCESS);
        }
        if (cp)
            *cp = '\0';
        else
      {
            printf("Employee name may be truncated.\n");
            myfflush();
      }

        /*  Prompt for the employee's job and salary. */
        printf("Enter employee job: ");
        job_ind = 0;
        fgets((char *) job, (int) joblen + 1, stdin);
        cp = (text *) strchr((char *) job, '\n');
        if (cp == job)
        {
           job_ind = -1;            /* make it NULL in table */
           printf("Job is NULL.\n");/* using indicator variable */
        }
        else if (cp == 0)
      {
            printf("Job description may be truncated.\n");
            myfflush();
      }
        else
            *cp = '\0';

        printf("Enter employee salary: ");
        scanf("%d", &sal);

       myfflush();
       sal_ind = (sal <= 0) ? -2 : 0; /* set indicator variable */

        /*
         *  Prompt for the employee's department number; verify
         *  that the entered department number is valid
         *  by executing and fetching.
         */
        do
        {
            printf("Enter employee dept: ");
            scanf("%d", &deptno);
            myfflush();
            if (oexec(&cda2) ||
                    (ofetch(&cda2) && (cda2.rc != NO_DATA_FOUND)))
            {
                err_report(&cda2);
                do_exit(EXIT_FAILURE);
            }  
            if (cda2.rc == NO_DATA_FOUND)
                printf("The dept you entered doesn't exist.\n");
        } while (cda2.rc == NO_DATA_FOUND);

        /*
         *  Increment empno by 10, and execute the INSERT
         *  statement. If the return code is 1 (duplicate
         *  value in index), then generate the next
         *  employee number.
         */
        empno += 10;
        if (oexec(&cda1) && cda1.rc != 1)
        {
            err_report(&cda1);
            do_exit(EXIT_FAILURE);
        }
        while (cda1.rc == 1)
        {
            empno += 10;
            if (oexec(&cda1) && cda1.rc != 1)
            {
                err_report(&cda1);
                do_exit(EXIT_FAILURE);
            }
        }  /* end for (;;) */

/* Commit the change. */
        if (ocom(&lda))
        {
            err_report(&lda);
            do_exit(EXIT_FAILURE);
        }
        printf("\n\n%s added to the %s department as employee 
                number %d\n", ename, dept, empno);
    }
    do_exit(EXIT_SUCCESS);
}


void
err_report(cursor)
    Cda_Def *cursor;
{
    sword n;
    text msg[512];

    printf("\n-- ORACLE error--\n");
    printf("\n");
    n = oerhms(&lda, cursor->rc, msg, (sword) sizeof msg);
    fprintf(stderr, "%s\n", msg);
    if (cursor->fc > 0)
        fprintf(stderr, "Processing OCI function %s",
            oci_func_tab[cursor->fc]);
}


/*
 *  Exit program with an exit code.
 */
do_exit(exit_code)
    sword exit_code;
{
    sword error = 0;

    if (oclose(&cda1))
    {
        fprintf(stderr, "Error closing cursor 1.\n");
        error++;
    }
    if (oclose(&cda2))
    {
        fprintf(stderr, "Error closing cursor 2.\n");
        error++;
    }
    if (ologof(&lda))
    {
        fprintf(stderr, "Error on disconnect.\n");
        error++;
    }
    if (error == 0 && exit_code == EXIT_SUCCESS)
        printf ("\nG'day\n");
    exit(exit_code);
}


void
myfflush()
{
  eb1 buf[50];

  fgets((char *) buf, 50, stdin);
}


cdemo2.c

/* This program accepts arbitrary SQL statements from the user,
   and processes the statement.  Statements may be entered on
   multiple lines, and must be terminated by a semi-colon.
   If a query, the results are printed. 
   Statements are entered at the OCISQL prompt.

   To quit the program, type EXIT at the OCISQL prompt.
   The size of the HDA is defined by the HDA_SIZE constant,
   which is declared in ocidem.h to be 256 bytes for 32-
   bit architectures and 512 bytes for 64-bit architectures.
*/

#include <stdio.h>
#include <ctype.h>
#include <string.h>

/* Include OCI-specific headers. */
#include <oratypes.h>
#include <ocidfn.h>
#ifdef __STDC__
#include <ociapr.h>
#else
#include <ocikpr.h>
#endif
#include <ocidem.h>

/* Constants used in this program. */
#define MAX_BINDS               12
#define MAX_ITEM_BUFFER_SIZE    33
#define MAX_SELECT_LIST_SIZE    12
#define MAX_SQL_IDENTIFIER      31
#define PARSE_NO_DEFER           0
#define PARSE_V7_LNG             2

/* Define one logon data area and one cursor data area
   Also define a host data area for olog.
   (See ocidfn.h for declarations). */
Lda_Def lda;
Cda_Def cda;
ub1     hda[HDA_SIZE];

/* Declare an array of bind values. */
text bind_values[MAX_BINDS][MAX_ITEM_BUFFER_SIZE];

/* Declare structures for query information. */
struct describe
{
    sb4             dbsize;
    sb2             dbtype;
    sb1             buf[MAX_ITEM_BUFFER_SIZE];
    sb4             buflen;
    sb4             dsize;
    sb2             precision;
    sb2             scale;
    sb2             nullok;
};

struct define 
{
    ub1             buf[MAX_ITEM_BUFFER_SIZE];
    float           flt_buf;
    sword           int_buf;
    sb2             indp;
    ub2             col_retlen, col_retcode;
};

/* Define arrays of describe and define structs. */
struct describe desc[MAX_SELECT_LIST_SIZE];
struct define   def[MAX_SELECT_LIST_SIZE];

/*  Declare this programs functions. */
sword  connect_user();
sword  describe_define();
sword  do_binds();
void   do_exit();
void   oci_error();
sword  get_sql_statement();
void   print_header();
void   print_rows();

/* Globals */
static text sql_statement[2048];
static sword sql_function;
static sword numwidth = 8;


main()
{
    sword col, errno, n, ncols;
    text *cp;

    /* Connect to ORACLE. */
    if (connect_user())
        exit(-1);

    /* Open a cursor, exit on error (unrecoverable). */
    if (oopen(&cda, &lda, (text *) 0, -1, -1, (text *) 0, -1))
    {
        printf("Error opening cursor.  Exiting...\n");
        ologof(&lda);
        exit(-1);
    }

    /* Process user's SQL statements. */
    for (;;)
    {
        /* Get the statement, exit on "exit". */
        if (get_sql_statement())
            do_exit(0);

        /* Parse the statement; do not defer the parse,
           so that errors come back right away. */
        if (oparse(&cda, (text *) sql_statement, (sb4) -1,
                 (sword) PARSE_NO_DEFER, (ub4) PARSE_V7_LNG))
        {
            oci_error(&cda);
            continue;
        }

        /* Save the SQL function code right after parse. */
        sql_function = cda.ft;

        /* Bind any input variables. */
        if ((ncols = do_binds(&cda, sql_statement)) == -1)
            continue;

        /* If the statement is a query, describe and define
           all select-list items before doing the oexec. */
        if (sql_function == FT_SELECT)
            if ((ncols = describe_define(&cda)) == -1)
                continue;

        /* Execute the statement. */
        if (oexec(&cda))
        {
            oci_error(&cda);
            continue;
        }

        /* Fetch and display the rows for the query. */
        if (sql_function == FT_SELECT)
        {
            print_header(ncols);
            print_rows(&cda, ncols);
        }

        /* Print the rows-processed count. */
        if (sql_function == FT_SELECT ||
            sql_function == FT_UPDATE ||
            sql_function == FT_DELETE ||
            sql_function == FT_INSERT)
            printf("\n%d row%c processed.\n", cda.rpc, 
                   cda.rpc == 1 ? '\0' : 's');
        else
            printf("\nStatement processed.\n");
    } /* end for (;;) */

}     /* end main() */


sword
connect_user()
{
    text username[132];
    text password[132];
    sword n;

    /* Three tries to connect. */
    for (n = 3; --n >= 0; )
    {
        printf("Username: ");
        gets((char *) username);
        printf("Password: ");
        gets((char *) password);
        if (olog(&lda, hda, username, -1, password, -1,
                 (text *) 0, -1, OCI_LM_DEF))
        {
            printf("Cannot connect as %s.\n", username);
            printf("Try again.\n\n");
        }
        else
        {
            return 0;
        }
    }
    printf("Connection failed.  Exiting...\n");
    return -1;
}

/*  Describe select-list items. */
sword
describe_define(cda)
Cda_Def *cda;
{
    sword col, deflen, deftyp;
    static ub1 *defptr;

    /* Describe the select-list items. */
    for (col = 0; col < MAX_SELECT_LIST_SIZE; col++)
    {
        desc[col].buflen = MAX_ITEM_BUFFER_SIZE;
        if (odescr(cda, col + 1, &desc[col].dbsize,
                   &desc[col].dbtype, &desc[col].buf[0],
                   &desc[col].buflen, &desc[col].dsize,
                   &desc[col].precision, &desc[col].scale,
                   &desc[col].nullok))
        {
            /* Break on end of select list. */
            if (cda->rc == VAR_NOT_IN_LIST)
                break;
            else
            {
                oci_error(cda);
                return -1;
            }
        }

        /* adjust sizes and types for display */
        switch (desc[col].dbtype)
        {
        case NUMBER_TYPE:
            desc[col].dbsize = numwidth;
            /* Handle NUMBER with scale as float. */
            if (desc[col].scale != 0)
            {
                defptr = (ub1 *) &def[col].flt_buf;
                deflen = (sword) sizeof(float);
                deftyp = FLOAT_TYPE;
                desc[col].dbtype = FLOAT_TYPE;
            }
            else
            {
                defptr = (ub1 *) &def[col].int_buf;
                deflen = (sword) sizeof(sword);
                deftyp = INT_TYPE;
                desc[col].dbtype = INT_TYPE;
            }
            break;
        default:
            if (desc[col].dbtype == DATE_TYPE)
                desc[col].dbsize = 9;
            if (desc[col].dbtype == ROWID_TYPE)
                desc[col].dbsize = 18;
            defptr = def[col].buf;
            deflen = desc[col].dbsize > MAX_ITEM_BUFFER_SIZE ?
              MAX_ITEM_BUFFER_SIZE : desc[col].dbsize + 1;
            deftyp = STRING_TYPE;
            break;
        }

        if (odefin(cda, col + 1,
                   defptr, deflen, deftyp,
                   -1, &def[col].indp, (text *) 0, -1, -1,
                   &def[col].col_retlen,
                   &def[col].col_retcode))
        {
            oci_error(cda);
            return -1;
        }
    }
    return col;
}


/*  Bind input variables. */
sword
do_binds(cda, stmt_buf)
Cda_Def *cda;
text *stmt_buf;
{
    sword i, in_literal, n;
    text *cp, *ph;

    /* Find and bind input variables for placeholders. */
    for (i = 0, in_literal = FALSE, cp = stmt_buf;
              *cp && i < MAX_BINDS; cp++)
    {
        if (*cp == '\'')
            in_literal = ~in_literal;
        if (*cp == ':' && !in_literal)
        {
            for (ph = ++cp, n = 0;
                 *cp && (isalnum(*cp) || *cp == '_')
                     && n < MAX_SQL_IDENTIFIER;
                 cp++, n++
                )
                ;
            *cp = '\0';
            printf("Enter value for %s: ", ph);
            gets((char *) &bind_values[i][0]);
            /* Do the bind, using obndrv().
               NOTE:  the bind variable address must be static.
               This would not work if bind_values were an
               auto on the do_binds stack. */
            if (obndrv(cda, ph, -1, &bind_values[i][0], -1, 
                       VARCHAR2_TYPE, -1, (sb2 *) 0, (text *) 0, 
                       -1, -1))
            {
                oci_error(cda);
                return -1;
            }
            i++;
        }   /* end if (*cp == ...) */
    }       /* end for () */
    return i;
}


/*  Clean up and exit.  LDA and CDA are
    global. */
void
do_exit(rv)
sword rv;
{
    if (oclose(&cda))
        fputs("Error closing cursor!\n", stdout);
    if (ologof(&lda))
        fputs("Error logging off!\n", stdout);
    exit(rv);
}


void
oci_error(cda)
Cda_Def *cda;
{
    text msg[512];
    sword n;

    fputs("\n-- ORACLE ERROR --\n", stderr);
    n = oerhms(&lda, cda->rc, msg, (sword) sizeof (msg));
    fprintf(stderr, "%.*s", n, msg);
    fprintf(stderr, "Processing OCI function %s\n",
            oci_func_tab[cda->fc]);
    fprintf(stderr, "Do you want to continue? [yn]: ");
    fgets((char *) msg, (int) sizeof (msg), stdin);
    if (*msg != '\n' && *msg != 'y' && *msg != 'Y')
        do_exit(1);
    fputc('\n', stdout);
}


sword
get_sql_statement()
{
    text cbuf[1024];
    text *cp;
    sword stmt_level;

    for (stmt_level = 1; ;)
    {
        if (stmt_level == 1)
        {
            /* Init statement buffer and print prompt. */
            *sql_statement = '\0';
            fputs("\nOCISQL> ", stdout);
        }
        else
        {
            printf("%3d     ", stmt_level);
        }

        /* Get (part of) a SQL statement. */
        gets((char *) cbuf);
        if (*cbuf == '\0')
            continue;
        if (strncmp((char *) cbuf, "exit", 4) == 0)
            return -1;

        /* Concatenate to statement buffer. */
        if (stmt_level > 1)
            strcat((char *) sql_statement, " ");
        strcat((char *) sql_statement, (char *) cbuf);

        /* Check for possible terminator. */
        cp = &sql_statement[strlen((char *) sql_statement) - 1];
        
        while (isspace(*cp))
            cp--;
        if (*cp == ';')
        {
            *cp = '\0';
            break;
        }
        stmt_level++;
    }
    return 0;
}


void
print_header(ncols)
sword ncols;
{
    sword col, n;
    fputc('\n', stdout);

    for (col = 0; col < ncols; col++)
    {
        n = desc[col].dbsize - desc[col].buflen;
        if (desc[col].dbtype == FLOAT_TYPE ||
            desc[col].dbtype == INT_TYPE)
        {
            printf("%*c", n, ' ');
            printf("%*.*s", desc[col].buflen,
                   desc[col].buflen, desc[col].buf);
        }
        else
        {
            printf("%*.*s", desc[col].buflen,
                   desc[col].buflen, desc[col].buf);
            printf("%*c", n, ' ');
        }
        fputc(' ', stdout);
    }            
    fputc('\n', stdout);
    for (col = 0; col < ncols; col++)
    {
        for (n = desc[col].dbsize; --n >= 0; )
            fputc('-', stdout);
        fputc(' ', stdout);
    }
    fputc('\n', stdout);
}

void
print_rows(cda, ncols)
Cda_Def *cda;
sword ncols;
{
    sword col, n;

    for (;;)
    {
        fputc('\n', stdout);
        /* Fetch a row.  Break on end of fetch,
           disregard null fetch "error". */
        if (ofetch(cda))
        {
            if (cda->rc == NO_DATA_FOUND)
                break;
            if (cda->rc != NULL_VALUE_RETURNED)
                oci_error(cda);
        }
        for (col = 0; col < ncols ; col++)
        {
            /* Check col. return code for null.  If
               null, print n spaces, else print value. */
            if (def[col].indp < 0)
                printf("%*c", desc[col].dbsize, ' ');
            else
            {
                switch (desc[col].dbtype)
                {
                case FLOAT_TYPE:
                   printf("%*.*f", numwidth, 2, def[col].flt_buf);
                   break;
                case INT_TYPE:
                   printf("%*d", numwidth, def[col].int_buf);
                   break;
                default:
                   printf("%s", def[col].buf);
                   n = desc[col].dbsize - strlen((char *)                                 def[col].buf);
                   if (n > 0)
                       printf("%*c", n, ' ');
                   break;
                }
            }
            fputc(' ', stdout);
        }
    }  /* end for (;;) */
}


cdemo3.c

/*
 *  cdemo3.c
 *
 *  Demonstrates using the oflng function to retrieve
 *  a portion of a LONG column.
 *
 *  This example "plays" a digitized voice message
 *  by repeatedly extracting 64 Kbyte chunks of the message
 *  from the table and sending them to a converter buffer
 *  (for example, a digital-to-analog converter's FIFO buffer).
 *
 *  To better understand this example, the table is created by
 *  the program, and some dummy data is inserted into it.
 *
 *  The converter subroutine is only simulated in this example
 *  program.
 *
 *  The size of the HDA is defined by the HDA_SIZE constant,
 *  which is declared in ocidem.h to be 256 bytes for 32-
 *  bit architectures and 512 bytes for 64-bit architectures.
 *
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MSG_SIZE        200000

#include <oratypes.h>
#include <ocidfn.h>

#ifdef __STDC__
#include <ociapr.h>
#else
#include <ocikpr.h>
#endif
#include <ocidem.h>

Cda_Def cda;
Lda_Def lda;
ub1     hda[HDA_SIZE];

dvoid do_exit();
dvoid oci_error();
dvoid play_msg();

main()
{
    text sql_statement[256];
    register sword i;
    sb2 indp;
    ub2 retl, rcode;
    sword msg_id;
    sb4 msg_len, len, offset;
    ub1 *ucp;
    register ub1 *ucp1;  
    ub4 ret_len;
    
    /* Connect to ORACLE. */
    if (olog(&lda, hda, (text *) "scott/tiger", -1,
              (text *) 0, -1, (text *) 0, -1, OCI_LM_DEF))
    {
        fputs("Cannot connect as SCOTT. Exiting...\n", stderr);
        exit(EXIT_FAILURE);
    }
    fputs("Connected to ORACLE as user SCOTT.\n", stdout);

    /* Open a cursor. */
    if (oopen(&cda, &lda, (text *) 0, -1,
              -1, (text *) 0, -1))
    {
        fputs("Cannot open cursor. Exiting...\n", stderr);
        exit(EXIT_FAILURE);
    }
    fputs("Program is about to drop the VOICE_MAIL table.\n",
           stdout);
    fputs("Is this OK (Y or N)? : ", stdout);
    fflush(stdout);




Go to previous file in sequence Go to next file in sequence
Prev Next
Oracle
Copyright © 1996 Oracle Corporation.
All Rights Reserved.
Go to Product Documentation Library
Library
Go to books for this product
Product
Go to Contents for this book
Contents
Go to Index
Index