关闭

otl编程指南

36人阅读 评论(0) 收藏 举报

1.  OTL 编程简介

1.1. 功能

OTLOracle ODBC 的模板库,它屏蔽数据库操作的底层,提供数据库连接功能,以标准 C++ 流的方式完成嵌入式 SQL 语句、存储过程的执行和光标操作。

OTL Oracle, Odbcand DB2-CLI Template Library 的缩写,是一个C++编译中操控关系数据库的模板库,它目前几乎支持所有的当前各种主流数据库,例如Oracle, MS SQL Server, Sybase, Informix, MySQL, DB2, Interbase / Firebird,PostgreSQL, SQLite, SAP/DB, TimesTen, MS ACCESS等等。OTL中直接操作Oracle主要是通过Oracle提供的OCI接口进行,进行操作DB2数据库则是通过CLI接口来进行,至于MS的数据库和其它一些数据库,则OTL只提供了ODBC来操作的方式。当然OracleDB2也可以由OTL间接使用ODBC的方式来进行操纵。

MS Windowsand Unix 平台下,OTL目前支持的数据库版本主要有:Oracle 7 (直接使用 OCI7), Oracle 8 (直接使用 OCI8), Oracle 8i (直接使用OCI8i), Oracle 9i (直接使用OCI9i), Oracle 10g (直接使用OCI10g), DB2 (直接使用DB2 CLI), ODBC 3.x ,ODBC 2.5OTL最新版本为4.0,参见http://otl.sourceforge.net/,下载地址http://otl.sourceforge.net/otlv4_h.zip
优点:
a. 跨平台
b. 运行效率高,与C语言直接调用API相当
c. 开发效率高,起码比ADO.net使用起来更简单,更简洁
d. 部署容易,不需要ADO组件,不需要.net framework

1.2. otl_connect

提供数据库连接、事务操作的功能。

SHBOSS开发中,由 CDBConnGuard 类屏蔽之并进行连接等管理。)

主要成员函数:

² intconnected; // 是否已经连接到数据库

² static intotl_initialize(const int threaded_mode=0); // 初始化 OTL 环境,必须在调用 OTL API 之前被调用;threaded_mode=1表示运行在多线程环境

² voidset_max_long_size(const int amax_size); // 设置缓冲区大小(仅对大数据字段适用

² otl_connect(constchar* connect_str,const int auto_commit=0); // connect_str的格式:USER/PASSWORD@TNS_ALIAS,如果是本地连接则不需要TNS_ALIAS

² void rlogon(constchar* connect_str,const int auto_commit=0);

² voidlogoff();

² void server_attach(const char* tnsname=0); // OTL/OCI8 only

² void server_detach();//OTL/OCI8 only

² session_begin(constchar* username, const char* password, const int auto_commit=0);// OTL/OCI8 only

² void session_end();//OTL/OCI8 only

² void session_reopen(constint auto_commit=0)// OTL/OCI8 only,打开用 session_end 关闭的会话

²  void commit();

²  void rollback();

²  注释:使用 serversession来登录比用 rlogon 效率更高

²  建议使用显式的commit 和rollback,不使用autocommit

1.3. otl_stream

1.3.1.   概述

以宿主调用和流的方式完成 SQL 语句的执行。

工作原理:先分析程序员指定的 SQL 语句,之后以流的方式把数据和 otl_stream 内部的缓冲区作交换,通过 flush() 将数据刷新到数据库中。

otl_nocommit_stream

 

1.3.2.   主要成员函数

otl_stream(

const short arr_size,

const char* sqlstm,

otl_connect&  db,

const  char* ref_cur_placeholder=0)

)

构造函数

arr_size表示缓冲记录的条数

sqlstm 表示要执行的  SQL 语句

db 表示使用的数据库连接

ref_cur_placeholder 表示返回的光标(如果有的话)的名字

void open(

const short arr_size,

const char* sqlstm,

otl_connect& db,

const char* ref_cur_placeholder=0)

)

同上

void close()

关闭流

int good()

测试流是否已经成功打开

int eof()

是否到了流的结尾,和标准 C++ 流的 eof 相同

void flush()

刷新 otl_stream 的缓冲区(获取新的数据或者把数据写到数据库中);当缓冲区满的时候,otl_stream 会自动 flush;如果设置了自动提交,则在  flush 的时候将会触发提交

void clean(const  int clean_up_error_flag=0)

清空缓冲区而不执行刷新操作

int is_null()

测试通过 >> 运算符获取的值是否为空

long get_rpc()

获取处理了的记录数目,限于INSERT、DELETE、UPDATE语句

otl_column_desc*  describe_select(int& desc_len);

获取字段描述信息,适用于SELECT语句、引用光标(OCI)和存储过程(ODBC for MS SQL Server and Sybase)

 

class  otl_column_desc{

public:

char name[512]; // column name

int dbtype; // database dependent,  column datatype code.

int otl_var_dbtype; // OTL defined,  column datatype code

int dbsize; // column length

int scale; // for numeric columns, column scale

int prec; // for numeric columns,  column precision

int nullok; // indicator whether  column is nullable or not

};

void  set_commit(

int  auto_commit=0

)

刷新(flush)缓冲区的时候,是否自动提交事务。从更易于理解的角度,建议在显式提交的应用中用 otl_nocommit_stream。

 

1.3.3.   OTL 的数据类型

otl_var_char 

 null terminated string (code=1)

otl_var_double 

 8 byte floating point number (code=2)

otl_var_float 

 4 byte floating point number (code=3)

otl_var_int 

 32 bit signed integer (code=4)

otl_var_unsigned_int 

 32 bit unsigned integer (code=5)

otl_var_short 

 16 bit signed integer (code=6)

otl_var_long_int 

 32 signed integer 9code=7)

otl_var_timestamp 

 datatype that is mapped into  TIMESTAMP_STRUCT, ODBC only (code=8)

otl_var_varchar_long 

 datatype that is mapped into LONG in Oracle  7/8, TEXT in MS SQL Server and Sybase (code=9)

otl_var_raw_long 

 datatype that is mapped into LONG RAW in  Oracle 7/8, IMAGE in MS SQL Server ad Sybase (code=10)

otl_var_clob 

 datatype that is mapped into CLOB in Oracle  8 (code=11)

otl_var_blob 

 datatype that is mapped into BLOB in Oracle  8 (code=12)

1.3.4.   示例

       otl_stream&  operator>>(char& c);

       otl_stream&  operator>>(unsigned char& c);

       otl_stream&  operator>>(char* s);

       otl_stream&  operator>>(unsigned char* s);

       otl_stream&  operator>>(int& n);

       otl_stream&  operator>>(unsigned& u);

       otl_stream&  operator>>(short& sh);

       otl_stream&  operator>>(long int& l);

       otl_stream&  operator>>(float& f);

       otl_stream&  operator>>(double& d);

       otl_stream&  operator>>(otl_long_string& s);

                         // read the LOB from the  stream

       otl_stream&  operator>>(TIMESTAMP_STRUCT& s);

                         // read the timestamp from  the stream

                         // (OTL 3.1/ODBC only)

       otl_stream&  operator>>(otl_datetime& dt);

               // read date/time info from the  stream

       otl_stream&  operator>>(otl_XXX_tab<…>& tab);

               // read PL/SQL tables from the stream  (OCIx)

      

       otl_stream&  operator>>(otl_lob_stream& lob);

                      // read reference to CLOB/BLOB  from otl_stream

                      // into otl_lob_stream (OCI8).  In other words,

                      // initialize otl_lob_stream  for reading CLOB/BLOB

                      // in stream mode

      

       otl_stream&  operator<<(const char c);

       otl_stream&  operator<<(const unsigned char c);

       otl_stream&  operator<<(const char* s);

       otl_stream&  operator<<(const unsigned char* s);

       otl_stream&  operator<<(const int n);

       otl_stream&  operator<<(const unsigned u);

       otl_stream&  operator<<(const short sh);

       otl_stream&  operator<<(const long int l);

       otl_stream&  operator<<(const float f);

       otl_stream&  operator<<(const double d);

       otl_stream&  operator<<(const otl_null n); // write NULL into the stream

       otl_stream&  operator<<(const otl_long_string& d);

                          // write the LOB into the stream

       otl_stream&  operator<<(const TIMESTAMP_STRUCT& d);

                          // write the timestamp  into the stream

                          // (OTL 3.1/ODBC only)

       otl_stream&  operator<<(const otl_datetime& dt);

                          // write date/time info into the stream

       otl_stream&  operator<<(const otl_XXX_tab& tab);

                          // write PL/SQL tables  into the stream (OCIx)

otl_stream&  operator<<(otl_lob_stream& lob);

                  // write otl_lob_stream descriptor  intoto otl_stream (OCI8).

                  // In other words, initialize  otl_lob_stream

                  // for writing CLOB/BLOB in stream  mode.

      

 

1.4. 错误处理(otl_exception)

classotl_exception {

public:

       char stm_text[2048]; // 导致异常的SQL 语句

       char var_info[256]; // 导致数据类型不兼容的邦定变量的名字

       unsigned char msg[1000]; // 数据库或者OTL的错误信息

       int code; // 错误代码

};

1.5. 其它

1.5.1.   使用邦定变量

示例:

INSERT INTO my_table VALUES(

:employee_id<int>,

:supervisor_name<char[32]>)

 

placeholder(比如employee_id)可以用没有意义的f1代替,但是在一个SQL语句中不能使用相同名字的placeholder

这里,支持的数据类型有:

int

 signed int

unsigned

 unsigned int

short

 short int

long

 long int

float

byte floating point number

double

byte floating point number

timestamp

 MS  SQL Server/Sybase DATETIME, Oracle DATE; requires TIMESTAMP_STRUCT  (OTL/ODBC), or otl_datetime  (both ODBC  and OCIx)

char[length]

 null terminated string; length is database  dependent; for Oracle in [3,32545]; for ODBC it depends on the database  backend and the ODBC driver

varchar_long

 for Oracle 7: LONG; for Oracle 8: LONG; for  ODBC: SQL_LONGVARCHAR

raw_long

 for Oracle 7: LONG RAW; for Oracle 8: LONG  RAW; for ODBC: SQL_LONGVARBINARY

clob

 for Oracle 8: CLOB

blob

 for Oracle 8; BLOB

 

1.5.2.   char 字段

在执行INSERT语句的时候,如果数据库中char字段的大小是n,则这个INSERT语句的邦定变量的大小要为n+1;否则当邦定变量的大小为n时,执行INSERT会出错。

例如:

INSERT INTO my_table VALUES(

:1<int>,:2<char[33]>,:3<double>,:4<char[129]>

)

这个例子中,my_table的第二和第四个字段的大小分别为32128

1.5.3.   number 字段

对数据库中定义的数字字段,可以根据字段的大小使用16位、32 位的整数和double类型;当然,如果对所有OCI的数字字段使用double,也不会出错。

1.5.4.   otl_datetime

       classotl_datetime{

       public:

         int year;

         int months;

         int day;

         int hour;

         int minute;

         int second;

       };

      

1.5.5.   otl_null

otl_null表示一个空值,当要INSERT一个空值到数据库中时,必须使用它。

otl_null的定义如下:

       class otl_null{

       public:

           otl_null(){}

           ~otl_null(){}

       };

1.6. 示例: insert&select

#include <iostream.h>

#include <stdio.h>

 

#define OTL_ORA8 // Compile OTL 3.1/OCI8

#include <otlv31.h> // include the OTL 3.1 header  file

 

otl_connect db; // connect object

     

void insert()

// insert rows into table

{

 otl_stream o(50, //  buffer size

               "insert into test_tab  values(:f1<float>,:f2<char[31]>)",

                 //  SQL statement

              db //  connect object

             );

 char tmp[32];

 

 for(int  i=1;i<=100;++i){

   sprintf(tmp,"Name%d",i);

   o<<(float)i<<tmp;

 }

}

 

void select()

{

 otl_stream i(50, //  buffer size

               "select * from test_tab where f1>=:f<int> and  f1<=:f*2",

                 //  SELECT statement

              db //  connect object

             );

   // create select  stream

 

 float f1;

 char f2[31];

 

 i<<8; //  assigning :f = 8

   // SELECT  automatically executes when all input variables are

   // assigned.  First portion of output rows is fetched to the buffer

 

 while(!i.eof()){ //  while not end-of-data

   i>>f1>>f2;

   cout<<"f1="<<f1<<",  f2="<<f2<<endl;

 }

 

 i<<4; //  assigning :f = 4

   // SELECT  automatically executes when all input variables are

   // assigned.  First portion of output rows is fetched to the buffer

 

 while(!i.eof()){ //  while not end-of-data

   i>>f1>>f2;

   cout<<"f1="<<f1<<",  f2="<<f2<<endl;

 }

 

}

 

int main()

{

 otl_connect::otl_initialize(); // initialize  OCI environment

 try{

 

   db.rlogon("scott/tiger"); // connect to Oracle

 

   otl_cursor::direct_exec

   (

    db,

    "drop table  test_tab",

     otl_exception::disabled // disable OTL exceptions

   ); // drop table

 

   otl_cursor::direct_exec

   (

    db,

    "create  table test_tab(f1 number, f2 varchar2(30))"

    );  // create table

 

  insert(); //  insert records into table

  select(); //  select records from table

 

 }

 

 catch(otl_exception& p){ // intercept  OTL exceptions

   cerr<<p.msg<<endl; // print out error message

   cerr<<p.stm_text<<endl; // print out SQL that caused the  error

   cerr<<p.var_info<<endl; // print out the variable that  caused the error

 }

 

 db.logoff(); //  disconnect from Oracle

 

 return 0;

 

}

 


 

Output

 

f1=8, f2=Name8

f1=9, f2=Name9

f1=10, f2=Name10

f1=11, f2=Name11

f1=12, f2=Name12

f1=13, f2=Name13

f1=14, f2=Name14

f1=15, f2=Name15

f1=16, f2=Name16

f1=4, f2=Name4

f1=5, f2=Name5

f1=6, f2=Name6

f1=7, f2=Name7

f1=8, f2=Name8

 

 

1.7. 参考文档

otl3.doc

Otl说明.doc

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:99次
    • 积分:4
    • 等级:
    • 排名:千里之外
    • 原创:0篇
    • 转载:2篇
    • 译文:0篇
    • 评论:0条
    文章存档