ORAPP - Oracle OCI C++ Interface Library

Using ORAPP: Simple SQL Statements
extern "C" {
#include <oci.h>
}

#include <orapp.hh>

int main(void) {
     ORAPP::Connection db;

     if (!db.connect("tns", "user", "pass")) {
         printf("failed to connect: %s\n", db.error().c_str());
         return 1;
     }

     /*
      * One can pre-propulate the Query object.
      */

     ORAPP::Query *q = db.query("SELECT 1 as one, 2 as two FROM dual");

     if (!q->execute()) {
         printf("failed to select: %s\n", db.error().c_str());
         return 1;
     }

     ORAPP::Row *r = q->fetch();

     /*
      * You can do type conversions directly in ORAPP by changing your
      * typecast of the Row object.
      */

     printf("one = %s, two = %u\n", (const char *)(*r)["one"], (unsigned)(*r)["two"]);

     /*
      * Or use the indirection operators to populate the Query.
      */

      *q << "INSERT INTO table (field) VALUES ('foobar')";

     if (!q->execute()) {
         printf("failed to execute: %s\n", db.error().c_str());
         return 1;
     }

     /*
      * ORAPP manages all its own memory, so in order to clean up all
      * that has to happen is that the main Connection object go out
      * of scope.
      */

      if (!db.disconnect()) {
          printf("failed to disconnect properly\n");
          return 1;
      }

      return 0;
}

Using ORAPP: Inbound and Outbound Bindings

extern "C" {
#include <oci.h>
}

#include <orapp.hh>

using namespace ORAPP;

int main(void) {
     Connection db;

     if (!db.connect("tns", "user", "pass")) {
         printf("failed to connect: %s\n", db.error().c_str());
         return 1;
     }

     /*
      * One can pre-propulate the Query object.
      */

     Query *q = db.query("BEGIN SELECT id, name INTO :id, :name WHERE age = :age; END");

     unsigned age = 25;

     q->bind(":age", age);

     unsigned id;
     char name[80] = {0};

     q->bind(":id", id);
     q->bind(":name", name, sizeof(name));

     /*
      * When doing bind()'s, only one execute() is required, which if
      * successful will populate any writable (inbound) bind's that
      * were specified.  Otherwise, if they were just read (outbound)
      * bind's, it would still be necessary to call fetch() (SELECTs).
      */

     if (!q->execute()) {
         printf("failed to select: %s\n", q->error().c_str());
         return 1;
     }

     /*
      * Variables should be populated now.
      */

     printf("age = %u, id = %u, name = %s\n", age, id, name);

     /*
      * ORAPP manages all its own memory, so in order to clean up all
      * that has to happen is that the main Connection object go out
      * of scope.
      */

      if (!db.disconnect()) {
          printf("failed to disconnect properly\n");
          return 1;
      }

      return 0;
}

For a more detailed and thorough demonstration of the capabilities of ORAPP, please see the test.cc program that comes packaged with this library.