OTL之Oracle开发总结《转》

简介:
OTL之Oracle开发总结---转
 

关 于OTL,网上介绍的也不少,但看来看去也只是官方的那些文档。OTL很好用,结合官方提供的一些例子,多多尝试才能领悟。经过一个月左右的项目开发,对 OTL也有些了解,在这里总结一下,希望对刚接触OTL的新手有所帮助。其中有些地方,比如对网络异常的处理,可是费了我两天的时间才解决的,我那个汗 哪。废话少说,开始正题:

一、开始前的准备工作

在使用OTL进行编程之前,要首先确定使用的Oralce版本以及所选用的字符集。OTL支持目前几乎所有的主流数据库,可以通过宏启用otlv4.h中对应的数据库操作接口。


如:使用oracle 11g R2、字符集选择UTF8,则可在包含otlv4.h之前声明以下两个宏:

 #define OTL_ORA11G_R2

#define OTL_ORA_UTF8

#include "otlv4.h"

....

二、常用类及其常用成员

1. otl_connect类

static int otl_initialize(const int threaded_mode=0):用于初始化OTL环境的静态函数,参数指定是用于多线程还是单线程。它不保证线程安全,也就是说,如果多个线程共享使 用一个otl_connect对象,需要加锁进行控制。有个同事因为在多线程环境下使用了默认的参数0,就导致了程序异常。但是单线程环境下,参数设1是 没有问题的。所以,可以考虑将此参数直接设为1。

void rlogon(...):这个函数有多个版本,请注意参考官方文档中与相应数据库版本对应的函数声明。11g中用到的参数说明如下:

const char *connect_str:连接字符串,格式为:"用户名/密码@数据库服务名"

const int aauto_commit:自动提交模式。若此参数设为0(默认),则通过此连接对象执行的事务不会自动提交。如使用direct_exec执行删除记录 的操作时,需要手动调用commit()成员函数提交事务;若设为1则通过此otl_connect对象开启的事务会自动提交。

long direct_exec(...):

const char *sqlstm: 指定所要执行的“静态SQL语句”,即不产生输入或输出的SQL语句。如delete from book where name='c++‘ 。但是不能执行如select sysdate from dual或select * from book亦或delete from book where name=:f1<char[20]>之类的语句,因为它们会带有输入或输出,此类SQL语句可以通过otl_stream实现,下面会有介 绍。

int ignore_error:是否忽略异常。可以指定otl_exception::disable禁用异常,否则程序需要使用try...catch(otl_exception &e)...捕获并处理异常。

int connected:此成员变量标识了连接对象是否连接成功,一旦连接成功其值即为1。即便后来网络断掉了,此值仍旧保持不变,logoff()后此值变为0。所以此变量只能用于检查rlogon是否连接成功,而不能判断当前与数据库的连接是否正常。

 

2. otl_stream类

void open(...):为流对象关联一个SQL语句,可以是带输入或输出的SQL语句或PL/SQL块。

const int arr_size:指定流缓冲区的大小。作为输出流使用时,若输出缓冲区中的记录数达到此值即缓冲区满时,会自动刷新缓冲区,若已设设置了自动提交则一并提交数据(默认);

const char *sqlstm:SQL语句,可以指定绑定变量,如:delete from book where id = :f1<int> and price = :f2<int>;

otl_connect &db:流所使用的数据库连接对象。

void set_commit(int auto_commit=0):设置流被刷新时否自动提交事务。两种条件下流会被刷新:a.缓冲区满   b.手动调用flush成员函数

void flush(...):执行和流关联的SQL语句。如执行:

otl_stream delStream;

delStream.open(100, delete from book where id = :f1<int> and price = :f2<int>, dbConnect);   //正常情况下向流中加入100条记录时才执行删除

delStream << 1;

delSteam << 'C++';

delStream.flush();         //立即执行删除操作,尽管当前流中只有一条记录

long get_rpc():获取流中SQL语句执行后所影响到的记录数,如插入100条记录,则调用此函数返回的即为100

int good():判断流对象是否已正常打开,已打开返回1。注意:若复用一个流对象时,必须先调用close函数将其关闭,然后再调用open重新打开。

int get_dirty_buf_len():获取当前流对象缓冲区中的记录数,其最大值为缓冲区size-1。每当缓冲区满时会自动刷新,刷新后再调用此函数时返回0

 

3.otl_exception类

该类的几个成员用于表示异常的信息,如:

char stm_text[2048]:出错的SQL语句;

char var_info[256]:若在流中使用了与实际类型不符的绑定变量,此数组的值为绑定变量的信息;

unsigned char msg[1000]:这个我比较喜欢用,此数组显示出具体的异常信息(包括oracle返回的错误码),如连接超时等等。

二、对于网络异常的处理

现在项目对于程序的异常处理能力要求越来越高,比如网络中断或数据库出现异常等,要求在故障恢复后,程序能正常与数据库保持连接,使业务尽可能的少受影响。可以通过以下方法解决此种情况。这也是折磨了我两天的一个问题:(

首先,程序要在提交数据的地方使用try...catch捕获otl_exception异常,当提交失败时,otl会抛出此异常并携带异常信息;


其次,要在捕获到异常之后,关闭之前的连接对象(如果有流使用此连接对象,则一定要先关闭流对象,然后再断开otl_connect对象);

最后,重新连接数据库并再次初始化流对象。

如:


void ReConnect(otl_connect &otlConnect, const char *pConnStr, int iAutoCommit);

 

....

//声明otl对象并初始化对象
otl_connect dbConn;
otl_stream outStream;

 

void Init(void)
{
 try
 {

  otl_connect::otl_initialize(1);
  dbConn.rlogon("");
  outStream.open(100, "insert into book values(:f1<int>, :f2<char[50]>, :f3<int>, :f4<char[20]>)", dbConn);
  outStream.set_commit(1);
 }
 catch (otl_exception &e)
 {
  //处理异常
 }
}

 

//提交数据的函数

void Submit(void)
{
 try
 {
  for (int i = 0; i < 5000; i++)
  {
   outStream << i;
   outStream << "abc";
   outStream << i;
   outStream << "null";
  }
 }
 catch(otl_exception &e)
 {

  //提交数据异常,重新连接数据库并重新初始化流对象
  outStream.close();       //必须先关闭流对象。若先断开连接会出现关闭流对象时报OCIHandleFree异常导致流对象无法正常关闭引起内存泄漏
  ReConnect(dbConn, "", 0);
  outStream.open(100, "insert into book values(:f1<int>, :f2<char[50]>, :f3<int>, :f4<char[20]>)", dbConn);
  outStream.set_commit(1);
 }
}

 

//重新连接连接数据库函数

void ReConnect(otl_connect &otlConnect, const char *pConnStr, int iAutoCommit)
{
 if (1 == otlConnect.connected)
 {
  otlConnect.logoff();
 }

Retry:
 try
 {
  otlConnect.rlogon(pConnStr, iAutoCommit);
 }
 catch (otl_exception &e)
 {
  Sleep(1000);
  goto Retry;
 }
}

这样,调用Submit函数提交数据时,就有了网络异常处理功能,若提交失败则会一直尝试重新连接,直到连接成功为止。

目录
相关文章
|
Oracle Java 关系型数据库
JSP struts2工资管理系统myeclipse开发oracle数据库bs框架java编程网结构
JSP 工资管理系统是一套完善的struts2设计系统MVC结构,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,开发环境为TOMCAT7.0,Myeclipse8.5开发,数据库为Oracle10g,使用java语言开发,系统主要采用B/S模式开发。
71 1
|
Oracle Java 关系型数据库
JSP停车场车位管理系统myeclipse开发oracle数据库BS模式java编程网
JSP 停车场车位管理系统是一套完善的web设计系统,对理解JSP java编程开发语言有帮助servlet+bean+dao (mvc模式开发),系统具有完整的源代码和数据库,开发环境为TOMCAT7.0,Myeclipse8.5开发,数据库为Oracle 10g,使用java语言开发系统主要采用B/S模式开发。
61 0
|
SQL Oracle 关系型数据库
开发必备:EsayCode使用以及Oracle自定义模板
写前先问一句,不会还有人在手动写这些基础的sql语句吧?! 最近在做Oracle的项目,手写mapper和entity文件真是写到手软,以前MySQL都是找的线上自动生成的,现在也不行了。 找了很长时间,也试验了一下mybaties-plus,后来要感谢掘金群里的老哥(图片已同意)。虽然默认模板很难用,但是自定义模板优化后,凑合可以使用吧。
|
Oracle 关系型数据库 BI
Oracle-分析函数_总结
Oracle-分析函数_总结
|
SQL Oracle 算法
Oracle总结【SQL细节、多表查询、分组查询、分页】下
在之前已经大概了解过Mysql数据库和学过相关的Oracle知识点,但是太久没用过Oracle了,就基本忘了…印象中就只有基本的SQL语句和相关一些概念….写下本博文的原因就是记载着Oracle一些以前没注意到的知识点…以后或许会有用… 实例与数据库概念
299 0
Oracle总结【SQL细节、多表查询、分组查询、分页】下
|
SQL Oracle 关系型数据库
Oracle总结【SQL细节、多表查询、分组查询、分页】上
在之前已经大概了解过Mysql数据库和学过相关的Oracle知识点,但是太久没用过Oracle了,就基本忘了…印象中就只有基本的SQL语句和相关一些概念….写下本博文的原因就是记载着Oracle一些以前没注意到的知识点…以后或许会有用… 实例与数据库概念
150 0
Oracle总结【SQL细节、多表查询、分组查询、分页】上
|
SQL 存储 Oracle
Oracle总结【视图、索引、事务、用户权限、批量操作】三
在Oracle总结的第一篇中,我们已经总结了一些常用的SQL相关的知识点了…那么本篇主要总结关于Oralce视图、序列、事务的一些内容… 在数据库中,我们可以把各种的SQL语句分为四大类… (1)DML(数据操纵语言):select,insert,update,delete (2)DDL(数据定义语言):create table,alter table,drop table,truncate table (3)DCL(数据控制语言):grant select any table to scott/revoke select any table from scott (4)TCL(事务
162 0
Oracle总结【视图、索引、事务、用户权限、批量操作】三
|
SQL Oracle 关系型数据库
Oracle总结【视图、索引、事务、用户权限、批量操作】二
在Oracle总结的第一篇中,我们已经总结了一些常用的SQL相关的知识点了…那么本篇主要总结关于Oralce视图、序列、事务的一些内容… 在数据库中,我们可以把各种的SQL语句分为四大类… (1)DML(数据操纵语言):select,insert,update,delete (2)DDL(数据定义语言):create table,alter table,drop table,truncate table (3)DCL(数据控制语言):grant select any table to scott/revoke select any table from scott (4)TCL(事务
189 0
Oracle总结【视图、索引、事务、用户权限、批量操作】二
|
SQL 存储 Oracle
Oracle总结【视图、索引、事务、用户权限、批量操作】 一
在Oracle总结的第一篇中,我们已经总结了一些常用的SQL相关的知识点了…那么本篇主要总结关于Oralce视图、序列、事务的一些内容… 在数据库中,我们可以把各种的SQL语句分为四大类… (1)DML(数据操纵语言):select,insert,update,delete (2)DDL(数据定义语言):create table,alter table,drop table,truncate table (3)DCL(数据控制语言):grant select any table to scott/revoke select any table from scott (4)TCL(事务
177 0
Oracle总结【视图、索引、事务、用户权限、批量操作】 一
|
存储 SQL Oracle