⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 otl1.htm

📁 ISO_C++:C++_OTL开发文档
💻 HTM
📖 第 1 页 / 共 5 页
字号:
Step 3 SQLObject *pDb=new SQLSybase(); 
          // Instantiate SQLObject object

Step 4 pDb->sqlLogin(); 
         // Log into the database

Step 5 pDb->sqlExec("SELECT name, address FROM customer");
        // execute the SQL command

Step 6 pDb->sqlBind(1,bindZSTRING,31,szName);
Step 7 pDb->sqlBind(2,bindZSTRING,31,szAddress);
        // Binds the host variables to the column results

Step 8 while(pDb->sqlFetch() == TRUE)
         {
           cout << szName << " " << szAddress << "\n";
         }
        // Fetches the records from the data source

Step 9 pDb->sqlDisconnect(); 
        // Disconnects from the data source

Step 10 delete pDb; // Deletes the object

</xmp>

<h4>The Same Sample Program in OTL streams</h4>
<p>
"As high as abstract and unified SQL stream interface":
</p>
<xmp>

Step 1 char szName[31];
Step 2 char szAddress[31];

Step 3 otl_stream  s(20, // stream buffer size (in rows)
                     "SELECT name, address FROM customer",
		        // SELECT statement
		     db // connect object
                    ; 


Step 4,5,6,7 
  // no explicit binding, no explicit execution

Step 8 while(!s.eof())
         {
	   s >> szName >> szAddress; // fetch one row
           cout << szName << " " << szAddress << endl;
         }
        // Fetches the records from the data source

Step 9, 10 
   // Automatic destructor will do the job

</xmp>

<h4>The Same Sample Program in OTL lower code layer </h4>
<p>
"As low as the Oracle Call Interface interface":
</p>
<xmp>

Step 1 char szName[31];
Step 2 char szAddress[31];

Step 3 otl_select_cursor s(db); // db -- connect object
          // Instantiate Cursor object

Step 4 // Everything is done in the constructor

Step 5 s.parse("SELECT name, address FROM customer");
        // Parse the SQL command

Step 6 s.bind_cstring(1,szName,30);
Step 7 s.bind_cstring(2,sAddress,30);
        // Binds the host variables to the column results

Step 8 while(s.next())
         {
           cout << szName << " " << szAddress << endl;
         }
        // Fetches the records from the data source

Step 9, 10
        // Automatic constructor will do the job
</xmp>

<h4><a name="sec222">2.2.2. OTL vs. DBTools.h++ (by Rogue Wave)</h4>

<h4>Sample Program in DBTools.h++</h4>
<xmp>

// This example establishes a connection to a SYBASE database, creates
// a table on the server, and uses the reader to read back the values.
// The values are then stored on a Memory Table and accessed row by
// row.  This example can run on both WINDOWS and SUN/SOLARIS or
// SUNOS.

//#define UNIX   // To run examples on Unix SunOS/Solaris

#define WINDOWS         // To run example on WINDOWS
#include <rw/db/db.h>
#include <rw/db/dbmgr.h>

#ifdef WINDOWS
#include <windows.h>
#endif

void write(const RWCString&  w)
{
#ifdef WINDOWS
  MessageBox(0,w.data(),"DBTOOLS_BOX",MB_OK);
#elif defined(UNIX)
  cout << w.data() << endl;
#endif
}

void errorHandler(const RWDBStatus& s)
{
  char buf[1040];
  sprintf(buf,"Message:  %s ",s.message().data());
  write(RWCString(buf));
}

#ifdef WINDOWS
#pragma argsused
int PASCAL WinMain(HINSTANCE , HINSTANCE, LPSTR, int )
{
  RWCString serverType("bdbsdld.dll");
#elif defined(UNIX)
int main()
{
  RWCString serverType("SYBASE");
#endif
     
  // Set the Error Handler
  RWDBManager::setErrorHandler(errorHandler);
  // Establish Connection
  RWDBDatabase adb = RWDBManager::database(serverType,
               "SYBASE100", // to the database.
               "henri",
               "meli12",
               "SUPPORT");
  if(!adb.isValid())
    write("Hmmm !!!  Cannot Connect. Exit...");
  else {
   RWDBConnection conn=adb.connection();
   if(adb.table("TABLE1").exists())
     adb.table("TABLE1").drop();

  RWDBSchema mySchema;
  mySchema.appendColumn("id_num",RWDBValue::Int);
  mySchema.appendColumn("id_type", RWDBValue::String, 15);
  mySchema.appendColumn("input_date", RWDBValue::DateTime);
  mySchema.appendColumn("price", RWDBValue::Float);
  adb.createTable("TABLE1",mySchema, conn);

  RWDBTable tab=adb.table("TABLE1");
  if(tab.exists())
    write("Table 'TABLE1' successfully created.");

  // Insert about 10 Values
  int numberOfEntries=5;
  char buffer[1040];
  RWDBDateTime date;
  float price=1.5f;

  RWDBInserter ins = tab.inserter();
  for(int i=0; i<numberOfEntries; i++)
  {
     sprintf(buffer,"Item%d",i);
     date.addDays(1);
     ins << i << RWCString(buffer) << date << << i*price;
     ins.execute(conn);
  }

  // Select all of items
  RWDBSelector sel = adb.selector();
  sel << tab;
  RWDBResult  res = sel.execute(conn);
  RWDBReader  rdr=res.table().reader(conn);
  RWDBMemTable memTab(rdr,numberOfEntries);
  for(i=0;i<memTab.entries(); i++)
  {
    sprintf(buffer,"ROW[%d]  ID_NUMBER %d  ID_TYPE %s \n 
     INPUT_DATE %s INPUT_PRICE %f\n", i,
          (memTab[i][0]).asInt(),
          (memTab[i][1]).asString().data(),
          (memTab[i][2]).asString().data(),
          (memTab[i][3]).asFloat());
    write(RWCString(buffer));
  }
  return 0;
 }
 return 0;
}

</xmp>

<h4>The Same Sample Program in OTL</h4>
<xmp>

// This example establishes a connection to an Oracle database, creates
// a table on the server, and reads the values back.

#include <stdio.h>
#include <iostream.h>
#include <otl.h>

otl_connect db; // connect object
void write(const char* w)
{
 cout << w << endl; // Write a message
}

int main()
{
 try{
  db.rlogon("scott/tiger"); // connect to Oracle
  otl_cursor::direct_exec
   (
    db,
    "drop table TABLE1",
    otl_exception::disabled // disable OTL exceptions
   ); // drop table
  otl_cursor::direct_exec
   (
    db,
    "create table TABLE1"
    "( "
    " id_num     number(8),"
    " id_type    varchar2(15),"
    " input_date date," 
    " price      number"
    ")"
    );  // create table
  write("Table 'TABLE1' successfully created.");

  // Insert about 10 Values
  {
   int numberOfEntries=5;
   char buffer[1040];
   int date=0;
   float price=1.5f;

   otl_stream ins(50, // buffer size (in rows)
		  "insert into TABLE1 values("
		  " :id_num<int>,"
		  " :id_type<char[64]>,"
		  " sysdate+:input_date<int>," 
		  " :price<float>"
		  ")",
		  db // connect object
		 );
   for(int i=0; i<numberOfEntries; i++){
    sprintf(buffer,"Item%d",i);
    ++date;
    ins << i << buffer << date << (float) i*price; 
      // insert one row into the table
   }
   
  }

  // Select all of items
  {
   char buffer[1040];
   int count=0;
   int id_num;
   char id_type[64];
   char input_date[32];
   float price;

   otl_stream sel(10, // buffer size (in rows)
		  "select * TABLE1"
		  db // connect object
		 );

   while(!sel.eof()){
    sel >> id_num >> id_type >> input_date >> price; 
      // get one row
    sprintf(buffer,
	    "ROW[%d]  ID_NUMBER %d  ID_TYPE %s \n"
	    "INPUT_DATE %s INPUT_PRICE %f\n", 
	    ++count,
	    id_num,
	    id_type,
	    input_date,
	    price
	   );
   }
  }

 }
 catch(otl_exception& p){ // intercept OTL exceptions
  write(p.msg);
 }

 db.logoff(); // disconnect from Oracle
 return 0;
}

</xmp>

<h2><a name="sec3">3. Library structure</h2>     

<p>
OTL falls into two parts: template classes to create host variables
and arrays and non-template classes to provide programming interface
to the Oracle Call Interface.
</p>

<h3><a name="sec31">3.1. Host variable and array template classes</h3>

<p>
Two types of host objects are distinguished: scalar
variables and arrays. OTL has two generic template classes
(otl_variable and otl_array) from which the following
specialized classes are derived:
</p>

<ul>
<li><i><b>Numerical data types</b></i>
<ul>
<li>otl_double, otl_double_array
<li>otl_signed_char, otl_signed_char_array
<li>otl_short_int, otl_short_int_array
<li>otl_int, otl_int_array
<li>otl_long_int, otl_long_int_array
<li>otl_unsigned, otl_unsigned_array
</ul>
</ul>

<ul>
<li><i><b>String data types</b></i>
<ul>
<li>otl_ctring, otl_cstring_array
<li>otl_varchar2, otl_varchar2_array
<li>otl_long, otl_long_array
<li>otl_varchar, otl_varchar_array
<li>otl_varraw, otl_varraw_array
<li>otl_raw, otl_raw_array
<li>otl_char, otl_char_array
<li>otl_charz, otl_charz_array
</ul>
</ul>


<ul>
<li><i><b>Data types for Oracle LONG and LONG RAW columns</b></i>
<ul>
<li>otl_long_varchar
<li>otl_long_varraw
</ul>
</ul>

<ul>
<li><i><b>Oracle internal data types (DATE, ROWID, VARNUM and NUMBER)</b></i>
<ul>
<li>otl_date, otl_date_array
<li>otl_rowid, otl_rowid_array
<li>otl_varnum, otl_varnum_array;
<li>otl_number, otl_number_array
</ul>
</ul>

<p>
The otl_variable and otl_array classes define the following
kinds of buffers which are necessary for handling host
variables:
<ul>
<li>value buffer (data member  <b>v</b>)
<li>indicator buffer (data member  <b>ind</b>)
<li>returned length buffer (data member  <b>rlen</b>)
<li>returned code buffer (data member  <b>rcode</b>)
</ul>
</p>
<p>
These data members are defined to be public, so the user has
access to them and may freely assign and change their
values.
</p>
<p>
The otl_variable and otl_array classes have a common parent
(otl_generic_variable) which contains information about the buffer
addresses, dimensions and data type codes. When a host variable or
array is constructed from an instantiated template, constructors of
the corresponding template classes initialize the data members of the
otl_generic_variable class. otl_cursor has a couple of the bind
functions which have the second parameter of the otl_generic_variable
type. Any template instantiated variables or arrays may be substituted
as actual parameters into those bind finctions.
</p>
<h3><a name="sec100">Class otl_generic_variable</h3>
<xmp>
class otl_generic_variable{
public:
</xmp>
<ul>
<li>Default constructor
<xmp>
otl_generic_variable();
</xmp>
<li>Destructor
<xmp>
virtual ~otl_generic_variable();
</xmp>
<li>Assigning a name to the variable
<xmp>
void copy_name(const char* aname);
</xmp>
<li>Assigning a position (number) to the select list item (column)
<xmp>
void copy_pos(const int apos);
</xmp>
<li>For input variable/array
<br><br>
<ul>
<li>Set variable's value as NULL
<xmp>
virtual void set_null(int ndx=0);
</xmp>
<li>Set variable's buffer length
<xmp>
virtual void set_len(int len, int ndx=0);
</xmp>
<li>Set variable's value as NOT NULL
<xmp>
virtual void set_not_null(int ndx=0);
</xmp>
</ul>
<li>For output variable/array
<br><br>
<ul>
<li>Check if variable's value is NULL
<xmp>
virtual int is_null(int ndx=0);
</xmp>
<li>Check if variable's value has been fetched OK
<xmp>
virtual int is_success(int ndx=0);
</xmp>
<li>Check if variable's value is truncated
<xmp>
virtual int is_truncated(int ndx=0);
</xmp>
<li>Get pointer to variable's buffer
<xmp>
virtual void* val(int ndx=0);
</xmp>
</ul>
<li>Only for output arrays, defined in SELECT statement
<ul>
<br><br>
<li>Check if during fetch conversion error occurred
<xmp>
virtual int is_invalid_conversion(int ndx=0);
</xmp>
<li>Check if during fetch real overflow occurred
<xmp>
virtual int is_real_overflow(int ndx=0);
</xmp>
<li>Check if variable has unsupported data type
<xmp>
virtual int is_unsupported_datatype(int ndx=0);
</xmp>
</ul>
</ul>
</ul>
<xmp>

protected:

</xmp>
<ul>
<li>pointer to buffer
<xmp>
ub1* p_v; 
</xmp>
<li>pointer to indicator variable/array
<xmp>
sb2* p_ind; 
</xmp>
<li>pointer to column's returned length
<xmp>
ub2* p_rlen; 
</xmp>
<li>poinetr column's returned code
<xmp>
ub2* p_rcode; 
</xmp>
<li>external data type's code of the host variable/array
<xmp>
int ftype; 
</xmp>
<li>array element/variable size
<xmp>
int elem_size; 
</xmp>
<li>host array size (=1 in case of scalar host variable)
<xmp>
int array_size; 
</xmp>
<li>variable name; 
<xmp>
char* name; 
</xmp>
<li>select list item position
<xmp>
int pos; 
</xmp>
</ul>
<xmp>
};
</xmp>

<h3><a name="sec101">Class otl_variable</h3>
<p>
This is the OTL template variable class. It is the base class for
constructing specialized host variable classes.
</p>
<xmp>
template <class T, int atype>
class otl_variable: public otl_generic_variable{
public:
</xmp>
<ul>
<li>Default constructor
<xmp>
otl_variable();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -