otl编程指南
来源:互联网 发布:java ftpclient api 编辑:程序博客网 时间:2024/06/07 22:34
1. OTL编程简介
1.1. 功能
OTL是Oracle和 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来操作的方式。当然Oracle和DB2也可以由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.5。OTL最新版本为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();
² 注释:使用 server、session来登录比用 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的第二和第四个字段的大小分别为32和128。
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》
- otl编程指南
- OTL 编程
- OTL编程接口
- OTL编程技术
- OTL编程接口
- 使用OTL进行数据库编程
- 使用OTL进行数据库编程
- 使用OTL进行数据库编程
- OTL
- 简单使用OTL进行数据库编程
- OTL 4.0, OTL 类
- 编程指南
- 编程指南
- OTL介绍
- Otl官方网站
- OTL简介
- OTL简介
- otl 数据库连接
- 跟随滑动的几种方法
- WPF log4Helper
- Android中so使用知识和问题总结以及插件开发过程中加载so的方案解析
- 非空二叉树的一个有趣的性质:n0 = n2 + 1
- Shiro实现用户登录
- otl编程指南
- Javascript—location
- uva11292勇士杀恶龙
- myeclipse新建项目需要配置的选项
- Learning Spark 笔记(七) -- 受益于分区的操作
- 使用JQuery使页面旋转90度
- spring aop 同一个bean中方法调用方法
- 配置Nginx反向代理需要注意的问题汇总
- React Native Sublime 中 Package Control 的安装与使用方法