The Cursor class provides support for Oracle REF CURSORs. It is derived from both the Nullable and Select_Stmt classes so that you may bind a Cursor object to a statement placeholder and then fetch from it. Many of the inherited member functions are defined as private, since they are inapppropriate for a Cursor.
Figure 3-6. class Cursor
namespace Oracle
{
class Cursor: public Select_Stmt, public Nullable
{
public:
// constructor/destructor
Cursor() throw(Error);
virtual ~Cursor() throw();
virtual void exec() throw(Error);
// accessors
virtual int sqlt() const throw(Error);
virtual int maxsize() const throw();
protected:
// implementors
virtual void* data() const throw();
virtual sb2* ind_addr() throw();
// data members
static Env env;
private:
// disallowed methods
virtual void set_null() throw();
virtual bool is_null() const throw();
virtual sb2 indicator() const throw();
virtual string str() const throw(Error);
virtual string str(const string&) const throw();
virtual string str(const string&, const string&) const throw();
virtual string sql_str() const throw();
virtual long lng() const throw(Error);
virtual long lng(const long) const throw();
virtual double dbl() const throw(Error);
virtual double dbl(const double) const throw();
};
}Upon construction, a Cursor object looks like an uninitialized Select_Stmt object. No useful operations may be performed on the object until it is bound to a statement (which retrieves a REF CURSOR) and that statement is executed. After this, the Cursor object can be used just like a Select_Stmt object in order to fetch() rows from it.
A Cursor object is used to represent the "result set" of a REF CURSOR. The most common way to create such a thing is to have an Oracle package which defines the following:
A record type
A cursor type returning that record type
A function which opens the cursor and then returns a reference to it
Example 3-2. An Oracle package using cursor references
PACKAGE jec
AS
TYPE mytable_rectype IS RECORD (
name mytable.name%TYPE,
phone mytable.phone%TYPE,
dob mytable.dob%TYPE);
TYPE mytable_curtype IS REF CURSOR RETURN mytable_rectype
FUNCTION open_mytable_cur RETURN mytable_curtype;
END jec;
PACKAGE BODY jec
AS
FUNCTION open_mytable_cur RETURN mytable_curtype
IS
mytable_curvar mytable_curtype;
BEGIN
OPEN mytable_curvar FOR
SELECT name,
phone,
dob
FROM mytable;
RETURN mytable_curvar;
END open_mytable_cur;
END jec;Here is the Ora++ code you would use to access this cursor:
Example 3-3. Using a Cursor object
// establish a connection object (connection is implicitly opened when
// stmt is constructed)
Connection db("/");
// prepare a call to the stored function
Cursor cur;
Non_Sel_Stmt stmt(db);
stmt << "begin " << bind(cur) << " := jec.open_mytable_cur(); end;";
// execute the stored function; cur then looks like an executed Select_Stmt
stmt.exec();
// now use cur like you would a Select_Stmt
Rowtype row;
cur.bind_col(row);
while (cur.fetch())
cout << row << endl;The first step is to prepare a call to the stored function which returns the cursor reference, binding the Cursor object at the appropriate position. After this statement is executed, the Cursor object can now be used like a Select_Stmt object. In this example, a Rowtype object is bound to the columns in the SELECT list, and then rows are fetched and processed.