1. 概述
OCI(Oracle Call Interfce), 即Oracle调用层接口,是Oracle公司提供的由头文件和库函数等组成的一个访问Oracle数据库的应用程序编程接口(application programming interface API),它允许开发人员在第三代编程语言(包括C\C++,COBOL和FORTRAN)中通过SQL来操纵Oracle数据库。
2. 性能比较
目前开发基于Oracle数据库的应用系统,可以选择多种工具,不仅用一般的数据库开发技术,如ODBC、JDBC等,同时,也可以用Oracle公司提供的专门开发工具,如Pro*C/C++、OCI等。比较这几种方式,前者是通用技术,开发起来比较容易,但弱点在于访问速度较慢, 如果要开发海量数据库应用系统, 这种速度是不能忍受的。所以需要采用OCI 开发, 因为它的访问速度比Pro* C/ C+ + 还快, 而且是一种底层接口, 几乎可以访问和控制Oracle 数据库的任何对象。由于OCI实现稍微复杂些,所以本项目组对OCI访问Oracle数据库的操作进行了封装,将OCI内部复杂函数调用转换成相对透明的函数接口,为上层应用提供效率更高、更简捷的数据库访问方式,使程序员更方便地进行数据库系统开发,达到高开发效率、程序可重用性和可维护性的目的,同时用C语言实现,平台移植性相对好一些。
| ODBC | JDBC | PRO*C | OCI |
通用性(关系数据库) | 所有 | 大部分 | Oracle | Oracle |
控制层次 | 高层 | 低层 | 底层 | 底层 |
是否使用oracle所以高级特性 | 不能 | 不能 | 能 | 能 |
复杂程度 | 简单 | 简单 | 简单 | 复杂 |
平台移植性 | 一般 | 很好 | 一般 | 很好 |
访问速度 | 低 | 较高 | 很高 | 非常高 |
3. 生成可执行程序流程
4. 程序的基本结构
在一个应用程序中,我们是通过调用OCI提供的库函数来实现对Oracle数据库的操纵。OCI提供了上百个函数,都是以OCI开头的函数,比如创建OCI环境的OCI函数:OCIEnvCreate()。OCI函数的一个特点或者说是难点就是它的参数特别多。一个OCI应用程序的基本结构包括:
1)初始化OCI环境和线程;
2)分配必要的句柄与数据结构;
3)建立与数据库的连接以及创建用户会话;
4)通过SQL与Oracle服务器交换数据,而后再做数据处理:
5)结束用户会话与断开与数据库的连接;
6)释放在程序中所分配的句柄。
示意如图2。
5. OCI应用程序中执行SQL的步骤
一个SQL语句在OCI应用程序中的执行步骤一般如下:
- 准备SQL语句。调用函数OCIStmtPrepare();
- 在SQL语句中绑定需要输入到SQL语句中的变量。对于DML语句来说,由于它带有输入变量,我们可以通过调用一个或者多个函数OCIBindByPos()、OCIBindByName()等把输入变量的地址绑定在DML语句中的占位符中;
- 执行SQL语句。调用OCIStmtExecute()函数。对于DDL语句到这一步就完成了一个语句的执行;
- 描述SQL中的输出的数据。如果有必要的话,我们可以调用函数OCIParamGet()与OCIAttrGet()来获取我们所读取的记录的字段个数、字段的数据类型以及字段数据定义的最大长度。
- 定义输出变量。对于DQL(Data Query Language)语句,即SELECT的查询语句,需要定义一定数量的变量用来接受所选择列的数据。我们可以调用OCIDeflneByPos()、OCIDefineObject()函数等来完成这个任务。也就建立SQL语句所返回的数据与应用程序中变量的关系。
- 获取数据。我们可以调用函数OCIStmtFetch()来把用SELECT选中的记录的数据赋予应用程序中的变量。过程以及过程中调用到的函数如图3所示:
虽然Oracle对标准的SQL语言有所扩展,但它也是建立在标准的SQL语言的基础之上。上图是一个一般SQL执行的流程图,对于不同的SQL语句,所需要的步骤也有所不同。对于DCL与DDL语句,由于没有数据的输入与输出,仅仅涉及到一些权限与定义或者删除数据库中的对象的问题,因此只需要上图的第一步与第三步便可以了。而对于DQL与DML语句,由于有数据的输入与输出,因此需要的步骤就多一些。其实,DML也可以只用两步来完成。这是因为DML语句中仅仅涉及数据的输入(即,数据从应用程序到数据库端),因此我们可以把所要输入的数据以字符串的形式放在SQL语句中。而DQL不仅可能有数据输入,而且也有数据输出(从数据库端到应用程序),因此,一个DQL语句需要如上图的六个步骤。
6. 引用的头文件和库
头文件:-I$(ORACLE_HOME)/precomp/public
-I$(ORACLE_HOME)/rdbms/public
-I$(ORACLE_HOME)/rdbms/demo
库文件:-L$(ORACLE_HOME)/lib
-L$(ORACLE_HOME)/lib32
-lclntsh