OTL资料简编

来源:互联网 发布:火箭炮手升级数据最新 编辑:程序博客网 时间:2024/05/14 23:24

简介:这是OTL资料简编的详细页面,介绍了和c/c++,有关的知识,加入收藏请按键盘ctrl+D,谢谢大家的观看!要查看更多有关信息,请点击此处

2.1.      OTL介绍

 

OTL 是 Oracle, Odbc and 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来操作的方式。当然Oracle和DB2也可以由OTL间接使用ODBC的方式来进行操纵。

 

在MS Windows and 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.5。OTL最新版本为4.0.193,参见http://otl.sourceforge.net/ 其中有对otl的介绍、源码下载、例子及文档、FAQ、作者的简历和一些有用的链接。

和 "OTL资料简编" 有关的c#、asp.net、c++编程小帖士:

strong>IndexOf()、LastIndexOf() 

查找字串中指定字符或字串首次(最后一次)出现的位置,返回索引值,如: 
str1.IndexOf("字"); //查找“字”在str1中的索引值(位置) 
str1.IndexOf("字串");//查找“字串”的第一个字符在str1中的索引值(位置) 
str1.IndexOf("字串",3,2);//从str1第4个字符起,查找2个字符,查找“字串”的第一个字符在str1中的索引值(位置) 

优点:
      a. 跨操作系统跨数据库
      b. 运行效率高,与C语言直接调用API相当
      c. 开发效率高,起码比ADO.net使用起来更简单,更简洁,整个库就只有一个头文件
      d. 部署容易,不需要ADO组件,不需要framework.net 等
缺点:
      a. 说明文档以及范例不足够丰富(暂时性的)

 

注意OTL的跨操作系统及跨数据库特性是由其调用具体数据库的接口而决定的,比如oracle可以通过OCI接口、db2可通过CLI接口。另外的一些数据库则是通过ODBC访问的,比如我需要在操作系统A上通过OTL访问数据库B,要么这个数据库满足otl特定的调用接口(比如oracle或db2),要么在此操作系统上存在odbc使得otl可以通过odbc来调用此数据库。

 

 

 

2.2.      OTL的使用

 

OTL使用起来也很简单,使用不同的数据库连接,主要是根据需要在程序开始的宏定义来指定的。 OTL是首先根据这个宏定义来初始化数据库连接环境。 OTL中用来区分连接方式的宏定义主要有下面这些:
 OTL_ORA7, OTL_ORA8, OTL_ODBC, OTL_DB2_CLI, OTL_ODBC_MYSQL...

 

不同的宏对应的数据库API,具体说明如下:

 

 

 





宏定义名



说明






OTL_DB2_CLI




for DB2 Call Level Interface (CLI)






OTL_INFORMIX_CLI




for Informix Call Level Interface for Unix (when  OTL_ODBC_UNIX is enabled).






OTL_IODBC_BSD




for ODBC on BSD Unix, when iODBC package is used






OTL_ODBC




for ODBC






OTL_ODBC_MYSQL




for MyODBC/MySQL. The difference between OTL_ODBC_MYSQL and OTL_ODBC is that transactional ODBC function calls are turned off for OTL_ODBC_MYSQL, since MySQL does not have transactions






OTL_ODBC_POSTGRESQL




for the PostgreSQL ODBC driver 3.5 (and higher) that are connected to PostgerSQL 7.4 / 8.0  (and higher)  servers.






OTL_ODBC_UNIX




for ODBC bridges in Unix






OTL_ODBC_zOS




for ODBC on IBM zOS.






OTL_ODBC_XTG_IBASE6




for Interbase 6.x via XTG Systems'  ODBC driver. The reason for introducing this #define is that the ODBC driver is the only Open Source ODBC driver for Interbase. Other drivers, like Easysoft's ODBC for Interbase, are commercial products, and it beats the purpose of using Interbase, as an Open Source.database server.






OTL_ORA7




for OCI7






OTL_ORA8




for OCI8






OTL_ORA8I




for OCI8i






OTL_ORA9I




for OCI9i. All code that compiles and works under #define OTL_ORA7, OTL_ORA8, and OTL_ORA8I, should work when OTL_ORA9I is used






OTL_ORA10G




for OCI10g. All code that compiles and works  under #define OTL_ORA7, OTL_ORA8, OTL_ORA8I, OTL_ORA9I, should work with OTL_ORA10G.






OTL_ORA10G_R2




for OCI10g, Release 2 (Oracle 10.2). All code that compiles and works  under #define OTL_ORA7, OTL_ORA8, OTL_ORA8I, OTL_ORA9I, and OTL_ORA10G should work with OTL_ORA10G_R2 .






我们在编译OTL的程序时,需要使用不同的头文件和数据库API,这就要程序在编译时联接lib库文件,不同的数据库对应的lib文件所在位置各不相同,下面是分别在windows与Unix下的数据库API所需要的头文件及lib文件所在的位置列表:

 

 

 






API




API header files for Windows




API libraries for Windows






OCI7




<ORACLE_HOME>/oci/include




<ORACLE_HOME>/oci/lib/<compiler_specific>/ociw32.lib






OCI8




<ORACLE_HOME>/oci/include




<ORACLE_HOME>/oci/lib/<compiler_specific>/oci.lib






OCI8i




<ORACLE_HOME>/oci/include




<ORACLE_HOME>/oci/lib/<compiler_specific>/oci.lib






OCI9i




<ORACLE_HOME>/oci/include




<ORACLE_HOME>/oci/lib/<compiler_specific>/oci.lib






OCI10g




<ORACLE_HOME>/oci/include




<ORACLE_HOME>/oci/lib/<compiler_specific>/oci.lib






ODBC




Normally, in one of the C++ compiler system directories, no need to include explicitly.




Normally, in one of the C++ compiler system directories: odbc32.lib






DB2 CLI




<DB2_HOME>/include




<DB2_HOME>/lib/db2api.lib
<DB2_HOME>/lib/db2cli.lib





 

 在Unix平台中:      

 

 

 

 

 

 

 

 

 






API




API header files for Unix




API libraries for Unix






OCI7




-I$(ORACLE_HOME)/rdbms/demo 


-I$(ORACLE_HOME)/rdbms/public




-L$(ORACLE_HOME)/lib/ -lclntsh






OCI8




-I$(ORACLE_HOME)/rdbms/demo 


-I$(ORACLE_HOME)/rdbms/public




-L$(ORACLE_HOME)/lib/ -lclntsh






OCI8i




-I$(ORACLE_HOME)/rdbms/demo


-I$(ORACLE_HOME)/rdbms/public




-L$(ORACLE_HOME)/lib/ -lclntsh






OCI9i




-I$(ORACLE_HOME)/rdbms/demo 


 -I$(ORACLE_HOME)/rdbms/public




-L$(ORACLE_HOME)/lib/ -lclntsh






OCI10g




-I$(ORACLE_HOME)/rdbms/demo


-I$(ORACLE_HOME)/rdbms/public




-L$(ORACLE_HOME)/lib/ -lclntsh






ODBC




ODBC bridge specific




ODBC bridge specific






DB2 CLI




-I/<DB2_HOME>/sqllib/include




-L/<DB2_HOME>/sqllib/lib -ldb2





 

从上面可以看出,如果在windows下操纵MS的 数据库,使用MS VC++来编译OTL程序,就非常简单了,不用另外去找ODBC32.lib,VC的编译器中已经默认link到工程中了,具体请看如何编译OTL:http://otl.sourceforge.net/otl3_compile.htm。

 

如果需要在vc下编译Oracle10g的工程则如下书写即可:

 

///////////////////////////////////////////

 

#define OTL_ORA10G     //这里必须在otlv4.h包含之前,otlv4.h使用了具体平台相关的宏定义

 

#include "..//..//otlv4_h/otlv4.h"   //otl库仅有的一个头文件

 

#pragma comment(lib,"oci.lib")       //windows下oci接口的静态导入库文件

 

///////////////////////////////////////////

 

同时在vc2003的c++工程中设置

 

工程->属性->C++->常规->附加包含目录为D:/oracle/product/10.1.0/db_1/OCI/include

 

工程->属性->连接器->常规->附加库目录为D:/oracle/product/10.1.0/db_1/OCI/lib/MSVC

 

注:这里我的操作系统<ORACLE_HOME>为D:/oracle/product/10.1.0/db_1/

 

3.    常用otl类

 

这里列出部分otl的常用类说明,这些资料在otl的在线文档http://otl.sourceforge.net/otl3_class.htm中有着更详细的解释,此处仅简要对其说明一下。

 

3.1.      otl_connect类

 

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

 

主要成员函数:

 

l        int connected; // 是否已经连接到数据库

 

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

 

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

 

l        otl_connect(const char* connect_str,const int auto_commit=0); // connect_str的格式:USER/PASSWORD@TNS_ALIAS

 

l        void rlogon(const char* connect_str,const int auto_commit=0);

 

l        void logoff();

 

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

 

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

 

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

 

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

 

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

 

l         void commit();

 

l         void rollback();

 

l         注释:使用 server、session来登录比用 rlogon 效率更高

 

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

 

3.2.      otl_stream类

 

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

 

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

 






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。当关闭了自动提交


set_flush(false),则需要显示调用flush()。


但一般情况建议使用自动提交缓冲,只要设置合理的缓冲大小即可,即不调用set_flush(false)






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()缓冲区的时候,是否自动提交事务,默认为1。从更易于理解的角度,建议在显式提交的应用中用 otl_nocommit_stream,但建议事务最好放到存储过程里做,在代码中将会变得很麻烦,代码中不再调用set_commit,使用默认自动提交为true。





 

 

 

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)





 

 

 

3.4.      otl的错误处理

 

class otl_exception {

 

public:

 

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

 

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

 

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

 

       int code; // 错误代码

 

};

 

 

 

3.5.      使用绑定变量

 

示例:

 

"insert into test_tab "

 

  "values(:nid<int>,:f2<char[32]>);"

 

占位符(比如nid)可以用没有意义的f1代替,但是在一个SQL语句中不能使用相同名字的占位符,在使用如上字符串构建otl_stream对象时otl将分配绑定变量的内存,在otl_stream析构时释放。如:

 

otl_stream o(32,                 //arr_size缓冲区可容纳的记录数

 

              "insert into test_tab "

 

              "values(:f1<int>,:f2<char[32]>);",//OTL将动态申请32字节的内存,调用完成后释放

 

              g_db //数据库连接对象

 

          );      

 

这里支持的数据类型如下表:

 






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






 

 

3.6.      char类型

 

在执行INSERT语句的时候,如果数据库中char字段的大小是n,则这个INSERT语句的绑定变量的大小需要定义为n+1,以使得在插入刚好n个字符的情况下留出0结束的位置(c/c++中需要有零结束符,数据库中就不需要了);

 

例如:

 

INSERT INTO my_table VALUES(

 

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

 

)

 

这个例子中,数据库中my_table的第二和第四个字段的大小分别为32和128。

 

3.7.      number类型

 

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

 

3.8.      otl_datetime

 

class otl_datetime{

 

       public:

 

         int year;

 

         int months;

 

         int day;

 

         int hour;

 

         int minute;

 

         int second;

 

       };

 

 

 

3.9.      otl_null

 

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

 

otl_null的定义如下:

 

       class otl_null{

 

       public:

 

           otl_null(){}

 

           ~otl_null(){}

 

       };

 

4.    实例代码

 

下面的代码展示了如果使用OTL连接Oracle10g并进行增、删、改、查及存储过程的调用操作,其中对需要注意的地方进行了详细注释。

 

编译前需要在vc2003的c++工程中设置如下:

 

工程->属性->C++->常规->附加包含目录为D:/oracle/product/10.1.0/db_1/OCI/include

 

工程->属性->连接器->常规->附加库目录为D:/oracle/product/10.1.0/db_1/OCI/lib/MSVC

 

注:这里我的操作系统<ORACLE_HOME>为D:/oracle/product/10.1.0/db_1/

 

 

 

// zhonglei

 

// 20090512

 

 

 

#include "stdafx.h"

 

 

 

#include <Windows.h>

 

#include <iostream>

 

using namespace std;

 

#include <stdio.h>

 

 

 

 

 

//指定Oracle10g的OCI调用

 

#define OTL_ORA10G

 

 

 

//OTL

 

#include "..//..//otlv4_h/otlv4.h"

 

#pragma comment(lib,"oci.lib")

 

 

 

//数据库对象

 

otl_connect g_db;

 

 

 

//普通存储过程调用

 

void procedure_normal(void);

 

 

 

//返回游标和字符串数组的存储过程调用

 

void procedure_cursor(void);

 

 

 

//创建表

 

int createtable(const char *sztb);

 

 

 

//删除表

 

int droptable(const char *sztb);

 

 

 

//插入记录

 

void insert(void);

 

 

 

//删除记录

 

void del(void);

 

 

 

//更新记录

 

void update(void);

 

 

 

//查询记录

 

void select(void);

 

 

 

//连接数据库

 

int connect(const char *szConnectstring);

 

 

 

//断开数据库

 

void disconnect();

 

 

 

int _tmain(int argc, _TCHAR* argv[])

 

{   

 

     //连接数据库

 

     if(connect("testuser/unsys@test"))

 

         return 1;

 

 

 

     //删除表

 

     if(droptable("test_tab"))

 

         return 1;

 

 

 

     //创建表

 

     if(createtable("test_tab(f1 int,f2 varchar2(32))"))

 

         return 1;

 

        

 

     insert();

 

     del();

 

     update();    

 

     select();

 

 //调用普通存储过程

     procedure_normal();   

 

    

 

     //调用返回游标和字符串数组的存储过程

 

     procedure_cursor();

 

 

 

     //断开数据库连接

 

     disconnect();

 

    

 

     system("pause");

 

    

 

     return 0;

 

}

 

 

 

/************************************************************************/

 

/*创建表

 

/************************************************************************/

 

 

 

int createtable(const char *sztb)

 

{

 

     try{

 

         char szBuf[256];

 

         sprintf(szBuf,"create table %s",sztb);

 

 

 

         otl_cursor::direct_exec

 

              (

 

              g_db,

 

              szBuf        

 

              ); 

 

 

 

         g_db.commit();

 

     }

 

     catch(otl_exception& p)

 

     {                

 

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

 

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

 

         cerr<<p.sqlstate<<endl; // print out SQLSTATE message 

 

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

 

         return 1;

 

     }

 

     printf("创建表%s/n",sztb);

 

     return 0;

 

}

 

 

 

/************************************************************************/

 

/*删除表

 

/************************************************************************/

 

 

 

int droptable(const char *sztb)

 

{

 

     try{

 

         char szBuf[256];

 

         sprintf(szBuf,"drop table %s",sztb);

 

 

 

otl_cursor::direct_exec


              (


              g_db,


              szBuf,


              otl_exception::disabled // 禁用异常功能


              );


 


         g_db.commit();


     }


     catch(otl_exception& p)


     {                


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


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


         cerr<<p.sqlstate<<endl; // print out SQLSTATE message 


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


         return 1;


     }


     printf("删除表:%s/n",sztb);


     return 0;


}


 


 


/************************************************************************/


/*普通存储过程


/************************************************************************/


 


void procedure_normal(void)


{


     printf(">>>普通存储过程/n");


     try{            


         //////////////////////////////////////////////////////////////////////////


         //创建存储过程        


         otl_cursor::direct_exec


              (


              g_db,


              "CREATE OR REPLACE Procedure procedure_normal(P1 In Number,P2 In Out Varchar2) Is/n"     //注意不要有/r,否则编译不过


              "Begin/n"         


              "P2 := P2 || P1;/n"             


              "End procedure_normal;"


              );


         g_db.commit();                  


         //////////////////////////////////////////////////////////////////////////


         //sql字符串


         char *szsql = "begin "


              "procedure_normal("


              ":1<int,in>,"         


              ":2<char[10240],inout>);"   //通知OTL流动态申请char[n]的缓冲,调用后释放(可换作char[1024*1024*1024/*1G*/]测试观察其内存变化)


                                          //在每次申请10241字节的情况下,循环调用此函数n次后内存都能够被及时回收


                                          //char[]的大小在输入输出时必须保证足够的空间


              "end;";


 


         //调用存储过程第一个参数为1


         otl_stream o(1,szsql,g_db);              


        


         int nPara1=999;


         char szPara2[10240] = "参数二";     


        


         //顺序给输入参数赋值(从左到右)


          o<<nPara1<<szPara2;


 


         //顺序取出输出参数(从左到右)


         o>>szPara2;


 


         printf("P1=%d/nP2=%s/n",nPara1,szPara2);


         printf("szPara2.Length=%d/n",strlen(szPara2));


     }


     catch(otl_exception& p)


     {                


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


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


         cerr<<p.sqlstate<<endl; // print out SQLSTATE message 


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


     }


}


 


/************************************************************************/


/*更新记录


/************************************************************************/


 


void update(void)


{


     printf("更新记录/n");


     try{


         otl_stream 


              o(1, // buffer size


              "UPDATE test_tab "


              "SET f2=:f2<char[32]> "         


              "WHERE f1=:f1<int>",       


              g_db


              );


         o<<"f2 changed"<<0;


     }


     catch(otl_exception& p)


     {                


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


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


         cerr<<p.sqlstate<<endl; // print out SQLSTATE message 


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


     }


}


 


/************************************************************************/


/*删除记录


/************************************************************************/


 


void del(void)


{


     printf("删除记录/n");


     try{


         otl_stream 


              o(1, // buffer size


              "Delete test_tab "              


              "WHERE f1=:f1<int>",       


              g_db


              );


         o<<1;


     }


     catch(otl_exception& p)


     {                


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


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


         cerr<<p.sqlstate<<endl; // print out SQLSTATE message 


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


     }


}


 


/************************************************************************/


/*插入记录


/************************************************************************/


 


void insert(void)


{


     printf("插入数据/n");


     try{    


         //arr_size缓冲区可容纳的记录数,当缓冲满时无论是否调用o.set_flush(false)都将自动提交缓冲


         //缓冲分配得太大则otl需要一次分配很大的内存


         //太小的话缓冲每填满一次就要IO一次


         //也就是时间换空间的概念


        


         //"insert into test_tab values(:f1<int>,:f2<char[33]>)",


         //OTL将动态申请33字节的内存,调用完成后释放,在insert字符串时这里的char[]需要比数据库中的多一个字节(c/c++中需要有0结束,数据库则不需要0结束)


 


         otl_stream o(8,    //记录缓冲大小        


              "insert into test_tab values(:f1<int>,:f2<char[33]>)",  //注意这里不要分号


              g_db //数据库连接对象


              );      


 


         //o.set_flush(false);


         //设置不自动提交流的缓冲区


         //更简洁的做法是设置合理的缓冲区大小,让OTL在缓冲区满的时间自动刷新


         //不是满一条记录就刷新(arr_size=1,这样IO会过于频繁)


         //也不要等到缓冲很大的时候才提交(缓冲将需要动态申请很大的内存,且每次提交数量巨大),比如1024


             


         char szBuf[33];


 


         //arr_size=8,实际插入32,缓冲需要刷新4次


         for(int i=0;i<32;i++)


         {


              sprintf(szBuf,"string[%d]",i);


              o<<i<<szBuf;


         }       


        


         //o.flush()


         //刷新 otl_stream 的缓冲区(获取新的数据或者把数据写到数据库中)       


         //当缓冲区满的时候(缓冲中记录数大于等于otl_stream的第一个参数arr_size)


         //不论是否调用o.set_flush(false); otl_stream也会自动flush,保证数据不会丢失


        


          //注意sql语句的提交和缓冲区的刷新没有直接关系


        


         //1.设置了set_flush(false)


         //arr_size=1


         //则缓冲中每满足一条记录就自动刷新一次到数据库


         //若arr_size=1024,但输入输出的记录数只有512,则所有语句在输入到流后也不会自动提交


         //必须使用flush()手动刷新缓冲


    


         //2.设置自动刷新缓冲set_flush(true)默认


         //arr_size=2048,实际插入1024,则在1024条记录输入到流完成后OTL将自动刷新缓冲    


     }


     catch(otl_exception& p)


     {                


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


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


         cerr<<p.sqlstate<<endl; // print out SQLSTATE message 


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


     }


}


 


/************************************************************************/


/*查询记录


/************************************************************************/


 


void select(void)


{


     printf("查询数据/n");


     try{


         otl_stream i(5, //stream buffer size can be > great 1 on SELECT.                        


              "select f1, f2 from test_tab",      


              g_db


              );


 


         int f1;


         char f2[32];      


 


         while(!i.eof())


         {


              i>>f1>>f2;


              printf("f1=%d/tf2=%s/n",f1,f2);                        


         }            


     }


     catch(otl_exception& p)


     {                


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


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


         cerr<<p.sqlstate<<endl; // print out SQLSTATE message 


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


     }


}


 


/************************************************************************/


/*连接数据库


/************************************************************************/


 


int connect(const char *szConnectstring)


{


     //初始化


     //threaded_mode=1表示运行在多线程环境


     otl_connect::otl_initialize(1);


    


     try


     {                 


         //Oracle登陆字符串形如:username/password@servicename


         //0-sql不自动提交


         g_db.rlogon(szConnectstring,0);


     }


     catch(otl_exception& p)


     {         


         cerr<<"connect failed!"<<endl;


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


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


         cerr<<p.sqlstate<<endl; // print out SQLSTATE message 


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


         return 1;


     }


     cout<<"数据库连接成功"<<endl;


     return 0;


}


 


/************************************************************************/


/*断开数据库


/************************************************************************/


 


void disconnect()


{   


     g_db.logoff();


     cout<<"连接断开"<<endl;


}


 


/************************************************************************/


/*


返回游标和字符串数组的存储过程                                         


关于使用otl调用返回游标的存储过程示例可参考


http://otl.sourceforge.net/otl4_ex153.htm


http://otl.sourceforge.net/otl4_ex150.htm


/************************************************************************/


 


void procedure_cursor()


{


     printf(">>>返回游标和字符串数组的存储过程/n");


     //////////////////////////////////////////////////////////////////////////


     // 创建包


     otl_cursor::direct_exec


         (g_db,


         "CREATE OR REPLACE PACKAGE my_pkg IS "


         " "


         "  TYPE my_cursor IS REF CURSOR; "             //定义游标类型


         "  TYPE my_tab IS TABLE OF VARCHAR2(100) INDEX BY BINARY_INTEGER;"    //定义表类型my_tab


         " "


         "  PROCEDURE my_proc "


         "    (f1_in IN NUMBER, "


         "     f2_in IN NUMBER, "


         "     str1 OUT my_tab, "


         "     cur1 OUT my_cursor, "


         "     cur2 OUT my_cursor); "


         " "


         "END; "


         );


 


     otl_cursor::direct_exec


         (g_db,


         "CREATE OR REPLACE PACKAGE BODY my_pkg IS "


         " "


         "  PROCEDURE my_proc "


         "    (f1_in IN NUMBER, "


         "     f2_in IN NUMBER, "


         "     str1 OUT my_tab, "


         "     cur1 OUT my_cursor, "


         "     cur2 OUT my_cursor) "


         "  IS "


         "    lv_cur1 my_cursor; "


         "    lv_cur2 my_cursor; "


         "  BEGIN "


         "    FOR i IN 1..7 LOOP "


         "      str1(i) := 'Line'||i; "


         "    END LOOP; "


         "    str1(8) := NULL; "


         "    OPEN lv_cur1 FOR "


         "      SELECT * FROM test_tab "


         "      WHERE f1>=f1_in  "


         "        AND f1<=f1_in*2; "


         "    OPEN lv_cur2 FOR "


         "      SELECT * FROM test_tab "


         "      WHERE f1>=f2_in  "


         "        AND f1<=f2_in*2; "


         "    cur1 := lv_cur1; "


         "    cur2 := lv_cur2; "


         "  END; "


         "   "


         "END; "


         );


     //////////////////////////////////////////////////////////////////////////


     otl_stream i(1, // buffer size


         "begin "


         " my_pkg.my_proc(:f1<int,in>,:f2<int,in>, "


         "         :str1<char[100],out[200]>, "//告诉otl申请内存的大小为char[200][100]


         // :str1 is an output PL/SQL table of strings parameter


         "         :cur1<refcur,out[50]>, "


         "         :cur2<refcur,out[50]>); "


         // :cur1, :cur2 are a bind variable names, refcur -- their types,


         // out -- output parameter, 50 -- the buffer size when this(otl_refcur_stream的记录缓冲数,满50即将流提交一次)


         // reference cursor will be attached to otl_refcur_stream


         "end;", // PL/SQL block that calls a stored procedure


         g_db // connect object


         );


 


     i.set_commit(0); // set stream "auto-commit" to OFF.


 


     otl_cstr_tab<200,101> str1; // PL/SQL table of char[200][101],用来存储返回记录的内存


     float f1;


     char f2[33];


     otl_refcur_stream s1, s2; // reference cursor streams for reading rows.


 


     i<<8<<4; // assigning :f1 = 8, :f2 = 4


     i>>str1; // reading :str1 from the stream


     i>>s1; // initializing the refeence cursor stream with the output


     // reference cursor :cur1


     i>>s2; // initializing the refeence cursor stream with the output


     // reference cursor :cur2


 


     cout<<"STR1_Len="<<str1.len()<<endl;


     for(int j=0;j<str1.len();++j)


         if(str1.is_null(j))


              cout<<"STR1["<<j<<"]=NULL"<<endl;


         else


              cout<<"STR1["<<j<<"]="<<str1.v[j]<<endl;


 


     cout<<"=====> Reading :cur1..."<<endl;


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


         s1>>f1>>f2;


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


     }


 


     cout<<"=====> Reading :cur2..."<<endl;


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


         s2>>f1>>f2;


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


     }


 


     s1.close(); // closing the reference cursor


     s2.close(); // closing the reference cursor


 


}


5.    参考资料


l         OTL官网:http://otl.sourceforge.net/


l         《OTL编程简介.doc》


l         《在跨平台的C++程序中使用OTL来操作不同的数据库》http://blog.csdn.net/roger_77/archive/2006/03/23/633132.aspx#965082


l         BrantDna的博客:http://blog.csdn.net/BrantDna/archive


 

 

"OTL资料简编"是由电脑编程网整理,请尊重作者权益,转载注明出处;

 相关文章
  • Eclipse 常用快捷键
  • Java新手的通病[5]:不了解JVM
  • ActionMessage 与ActionErrors
  • Windows下JDK环境变量的设置
  • struts-config.xml配置文件
  • XMLHttpRequest编写AJAX应用步骤
  • 搜索文本内容——Java代码的简单实现(修改版)
  • Openfire Connection Manager 配置
  • 一个简单的实现不同权限的用户登录后看到不同的菜单设计的数据库表清单
  • MySQL中文乱码问题解析
  • Java编程那些事儿98——多线程问题及处理1
  • 关于参数传递
  • 在weblogic 8.x中快速部署工程
  • MD5(Java版)
  • c# 自定用户控件配置(两种情况)
  • AfxGetApp用法
  • XML Form Generator: 由Xml生成Form表单
  • .NET StringBuilder跟String的区别
  • DbCommand 参数
  • 初窥SOCKET
  • 不能在Validating时弹出有模式的对话框
  • 纯C#打造WPF游戏引擎系列高级教程(WPF game course)之:(三)让物体动起来
  • petshop4中profile的配置
  • ASP.NET 数据绑定 Web 服务器控件概述
  • 纯C#打造WPF游戏引擎系列高级教程(WPF game course)之:(六)完美移动
  • [实践笔记]grub引导手工安装winPE到移动硬盘
  • Head First C# 中文版 第九章 读写文件 page434
  • 系统数据库灾难恢复
  • 依赖自动统计对性能的影响
  • EIR软件(高校版)--中国高校教育管理的首选软件

原创粉丝点击