OraLib - a lightweight C++ wrapper over Oracle's OCI library
<< TOC >>
Following code should make a list with objects (that is tables, packages, sequences, etc.) for Scott Tiger (Oracle sample) database schema.
...
cn.open ("server_name", "scott", "tiger");
oralib::resultset &rs = *cn.select (
"select OBJECT_NAME, OBJECT_TYPE, TIMESTAMP, STATUS from OBJ");
oralib::column &col = rs ["OBJECT_TYPE"];
while (!rs.eod ())
{
_tprintf (_T ("%-18s %-18s %-20s %s\n"),
(oralib::Pstr) rs ["OBJECT_NAME"],
(oralib::Pstr) col,
(oralib::Pstr) rs [3],
(oralib::Pstr) rs [4]);
rs.next ();
}
rs.release ();
cn.close ();
...
Sample output (but for different schema):
... CART_PKG PACKAGE 2001-12-09:19:31:05 VALID CART_PKG PACKAGE BODY 2001-12-09:19:31:06 VALID CATEGORIES TABLE 2001-12-09:19:30:58 VALID CAT_CID INDEX 2001-12-09:19:31:00 VALID CAT_PK INDEX 2001-12-09:19:30:59 VALID CAT_SEQ SEQUENCE 2001-12-09:19:31:00 VALID ...
...
oralib::statement &s = *c.prepare ("begin :n1 := :n2 * 2; end;");
oralib::parameter &p = s.bind (":n1");
s.bind (":n2") = (long) 40;
s.execute ();
_tprintf (_T ("%d\n"), (long) p);
p.release ();
s.release ();
...
oralib::statement &s = *c.prepare (
"insert into TableName values (:n1)");
oralib::parameter &p = s.bind (":n1");
for (int i=0; i<1000; ++i, p = (long) i)
s.execute ();
s.release ();
c.commit ();
Prepared statements executed multiple times are about two-times faster than statements, prepared before each execution (when Oracle server and the client are running on a same machine).
Following SQL code will create database tables used (if you don't have demo database installed):
create table EMP
(
EMPNO numeric,
ENAME varchar2 (50),
JOB varchar2 (50),
SAL numeric,
DEPTNO numeric
);
alter table EMP add constraint EMP_PK primary key (EMPNO);
create table DEPT
(
DEPTNO numeric,
DNAME varchar2 (50)
);
alter table DEPT add constraint DEPT_PK primary key (DEPTNO);
insert into DEPT values (1, 'Management');
insert into DEPT values (2, 'Support');
insert into DEPT values (3, 'Sales');
insert into DEPT values (4, 'Production');
insert into DEPT values (5, 'QA');
commit;
OraLib port of cdemo81.c source (original cdemo81.c is more than 400 lines long; this one is about a 100):
void cdemo81 (void)
{
oralib::connection cn;
try
{
// connect
cn.open ("ora1", "thesis", "thesis");
// retrieve the current maximum employee number
oralib::resultset &rs = *cn.select ("SELECT NVL(MAX(empno), 0) FROM emp");
sword empno = (sword) (long) rs [1];
rs.release ();
// prepare both statements for execution
oralib::statement &st_insert = *cn.prepare (
"INSERT INTO emp(empno, ename, job, sal, deptno) "
"VALUES (:nEmpno, :sEname, :sJob, :nSal, :nDeptno)");
oralib::statement &st_dep_name = *cn.prepare (
"SELECT dname FROM dept WHERE deptno = :nDeptno");
// bind named variables
st_insert.bind (":nEmpno");
st_insert.bind (":sEname");
st_insert.bind (":sJob");
st_insert.bind (":nSal");
st_insert.bind (":nDeptno");
st_dep_name.bind (":nDeptno");
while (true)
{
std::string ename, ejob, dept;
sword esal, deptno;
// get information
std::cout << "\nEnter employee name (or Ctrl+Z, Enter to EXIT): ";
std::cin >> ename;
if (ename.length () == 0) break;
std::cout << "Enter employee job: ";
std::cin >> ejob;
std::cout << "Enter employee salary: ";
std::cin >> esal;
// ask for department and verify that exists
bool found = false;
do
{
std::cout << "Enter employee dept: ";
std::cin >> deptno;
st_dep_name [1] = (long) deptno;
oralib::resultset &rs = *st_dep_name.select ();
found = !rs.eod ();
if (found)
dept = rs [1].as_string ();
else
std::cout << "The dept you entered doesn't exist.\n";
rs.release ();
}
while (!found);
// insert an employee record
st_insert [":sEname"] = ename.c_str ();
st_insert [":sJob"] = ejob.c_str ();
st_insert [":nSal"] = (long) esal;
st_insert [":nDeptno"] = (long) deptno;
bool succeeded = false;
do
{
st_insert [":nEmpno"] = (long) empno;
try
{
st_insert.execute ();
cn.commit ();
succeeded = true;
}
catch (oralib::error &e)
{
empno += 10;
}
}
while (!succeeded);
std::cout << ename << " added to the " << dept <<
" department as employee number " << empno;
}
st_insert.release ();
st_dep_name.release ();
cn.close ();
}
catch (oralib::error &e)
{
e.display ();
}
}