Sometime toward the end of March 2000, I was assigned the task of maintaining a set of C++ programs that used Pro*C as the interface to Oracle. I've used Pro*C often in the past, but always with C. Now, rather than Pro*C being my friend, it was getting in the way of using object-oriented design.
What I wanted was an object-oriented interface to Oracle for C++ similar to those in Java's JDBC, Python or PERL, but I couldn't find one. So, over the following weekend, I wrote the initial version of Ora++. The interface has been expanded since then, but the basic structure has not changed. Most of my modifications have been adding syntactic sugar and increasing its robustness.
When looking at the examples presented here, please keep in mind that this document may not be completely current. I plan on regularly updating the source code on the site as I improve its stability, and I may not always update this page to reflect changes to the interface. The most authoritative source for information is, of course, the source code.
Here's a code fragment using Ora++:
Example 1-1. An Ora++ example
Connection db("fred/smerd@dbname");
db.open();
Select_Stmt stmt(db, "SELECT col1, col2 FROM mytable");
Varchar col1(30);
Number col2;
stmt.bind_col(col1); // output
stmt.bind_col(col2); // output
stmt.exec();
while(stmt.fetch())
cout << col1 << ", " << col2 << endl;
db.close();Example 1-1 demonstrates the basics of initiating a connection and preparing a SQL statement. It also shows the use of the bind_col() method to specify a host variable to hold the value of a selected column.
If bind_col() is not called for a SELECT statement before the fetch() method is called, the statement object will allocate its own space to hold the retrieved column values. You access these using the col() method:
Example 1-2. An Ora++ example without bind_col()
Varchar col3("Fred");
Connection db("fred/smerd@dbname");
db.open();
Select_Stmt stmt(db, "SELECT col1, col2 FROM Friends WHERE col3 = :col3");
stmt.bind(col3); // input
stmt.exec();
while(stmt.fetch())
cout << stmt[0] << ", " << stmt["COL2"] << endl;
db.close();Notice in Example 1-2 that you may use either the column name or the zero-based position of the column in the SELECT list as the argument to col().
There is another variation in creating statements to allow greater flexibility in building dynamic SQL: statement objects are also stringstreams, which may be written to like any output stream. Example 1-3 is a version of the previous example using the stream feature.
Example 1-3. An Ora++ example using a statement as a stream
Varchar col3("Fred");
Connection db("fred/smerd@dbname");
db.open();
Select_Stmt stmt(db);
stmt << "SELECT col1, col2 FROM Friends WHERE col3 = " << bind(col3);
stmt.exec();
while(stmt.fetch())
cout << stmt[0] << ", " << stmt["COL2"] << endl;
db.close();You may notice that there is also a manipulator called bind(). This manipulator inserts a placeholder at that point in the output stream and adds the specified variable to a queue. When exec() is called, each variable in the queue is bound to its placeholder before the statement is executed.