ocienvcreate php 失败_OCI 学习笔记(转)

这段自学 OCI 编程,感觉网上这方面的资料其实也不少,只是不是很容易找到。其实 OCI

没有想象的那么复杂,如果你想深究,那应该就只是时间问题。我在网上看到有人这么写到,对于 C 高手来说 OCI

编程只是简单的调用接口函数而已。我个人认为,学习 OCI 编程真的没那么难的,如果你想简单的会使用。

那么接下来我就这段时间对 OCI 函数的学习及所收集的资料进行整合,用于帮助那些刚刚接触 OCI 编程的程序员,及 OCI

编程专家做以讨论及研究。当然以下贴出的程序虽然都已经在 x86_64-redhat-linux 系统, GCC 版本 4.1.1

20070105 (Red Hat 4.1.1-52) 下通过编译, OCI

每个函数的参数都有严格的类型定义,比较繁琐,下面的函数示例为了简洁说明,没有对错误进行处理,在实际应用中是应该注意的。

但有些个人结论并非正确,还请大家自己进行测验,得出正确结果后希望给予指正,在下不胜感激。

一、理论:

在这里不废话的解释什么是 OCI 及 OCI 简介。不过值得一提的是 OCI 程序的编译,下边就先对 OCI

程序怎么编译,编译过程中出现的问题做出详细解释。

1 、在此只说 UNIX/LINUX 下 OCI 编程的配置。

在 UNIX 下编译 OCI 程序需要 3 个必要条件:

(1) 需要 oci.h 文件的所在目录。一般为 ORACLE 的安装目录:

/…/10.2.0/db_1/rdbms/public/ 。

(2) OCI 的静态链接库文件。静态库文件在我这是在用户目录下有个 lib 文件夹静态文件名为 ora.a ,其目录是:

/user/lib 。

这个静态文件的生产方式是用户目录下有个 OCI 文件夹,目录为: /user/oci ,是 ORACLE 的应用程序,直接

make 就可以生产该静态库了。 -- 有待考核

(3) 在编译时需要再加几个静态库 -lclntsh -lm –lnsl 我想这几个应该是 ORACLE 数据库运行 OCI

程序的驱动库文件吧。如果不加则会提示你程序中所有 OCI 函数找不到其定义。另外还需要加这些库文件的所在地址。

(4) 另附 makefile 文件

view plaincopy to clipboardprint?

FLAGS = -g

-m64 #编译OCI程序时所用到的头文件路径 INCLUDE_PATH = \ -I ${ORACLE_HOME}/rdbms/demo

\ -I ${ORACLE_HOME}/rdbms/public

\ -I ${ORACLE_HOME}/plsql/public

\ -I ${ORACLE_HOME}/network/public

\ -I ${ORACLE_HOME}/precomp/public

\ -I . #编译OCI程序时所用到的静态链接库路径 LIB_PATH = -L${HOME}/billing/lib

\ -L${ORACLE_HOME}/lib/ \ -L${ORACLE_HOME}/rdbms/lib/ #编译OCI程序时所用到的静态链接库 LIBS =/billing/billing/lib/ora.a -lm -lnsl

-lclntsh myoci:myoci.cpp g ${FLAGS} -o myoci myoci.cpp ${INCLUDE_PATH} ${LIBS} ${LIB_PATH} clean: rm -f ./core* myoci FLAGS = -g -m64

#编译OCI程序时所用到的头文件路径

INCLUDE_PATH = \

-I ${ORACLE_HOME}/rdbms/demo \

-I ${ORACLE_HOME}/rdbms/public \

-I ${ORACLE_HOME}/plsql/public \

-I ${ORACLE_HOME}/network/public \

-I ${ORACLE_HOME}/precomp/public \

-I .

#编译OCI程序时所用到的静态链接库路径

LIB_PATH = -L${HOME}/billing/lib \

-L${ORACLE_HOME}/lib/ \

-L${ORACLE_HOME}/rdbms/lib/

#编译OCI程序时所用到的静态链接库

LIBS =/billing/billing/lib/ora.a -lm -lnsl -lclntsh

myoci:myoci.cpp

g ${FLAGS} -o myoci myoci.cpp ${INCLUDE_PATH} ${LIBS} ${LIB_PATH}

clean:

rm -f ./core* myoci

注意:以上路径都是相对路径,是根据你的 ORACLE

安装目录而决定的。在此贴出只是当作参考。 Windows 下 VC

的配置和以上步骤差不错,把相应的所需头文件及其目录,静态文件及其链接库,添加到项目工程的配置里即可,在此不再一一指出。

2 、句柄层次

OCI 使用各种句柄操作数据库,环境句柄( Environment Handle

)是所有句柄的父句柄。由于贴图不够详细我把相应的 OCI 文档及资料已经上传到我的下载中,请下载后进行查阅。

a4c26d1e5885305701be709a3d33442f.png

服务器句柄 ( Server Handle ),用户会话句柄( User Session

Handle ),事务句柄( Transaction Handle )隶属于服务上下文句柄( Service Context

Handle ),但都是以环境句柄为父句柄分配的。

查询输出定位句柄( Define Handle )和输入输出绑定变量句柄( Bind Handle )在执行具体的 SQL

语句的时候,被隐含创建并连接到表达句柄( Statement Handle )上,当表达句柄释放时,它们也被隐含释放。所以在执行每一个

sql 语句时,先分配表达句柄,执行结束后,释放表达句柄,这样做保证不发生由于定位句柄和绑定变量句柄引起的内存泄漏。

3 、连接 ORACLE 数据库流程

OCI 连接过程十比较复杂,除了分配设置各个基本句柄外,还要明确彼此之间的联系,大致流程如下:

创建环境句柄: OCIEnvCreate(&envhp, …);

创建一个指定环境的错误句柄: OCIHandleAlloc((dvoid *)envhp, (dvoid

**)&errhp,…);

创建一个指定环境的服务句柄: OCIHandleAlloc((dvoid *)envhp, (dvoid

**)&servhp,…);

建立到数据源的访问路径 : OCIServerAttach(servhpp, errhpp,…);

创建一个指定环境的服务上下文句柄: (void) OCIHandleAlloc((dvoid *)envhpp,…);

为指定的句柄及描述符设置特定的属性: (void) OCIAttrSet((dvoid *)svchpp,…);

创建一个指定环境的用户连接句柄: (void) OCIHandleAlloc((dvoid *)envhpp,…);

为用户连接句柄设置登录名及密码: (void) OCIAttrSet((dvoid *)usrhpp,…);

认证用户建立一个会话连接: OCISessionBegin(svchpp, errhpp,…);

创建一个句子句柄: OCIHandleAlloc((dvoid *)envhpp,…);s

准备 SQL 语句: OCIStmtPrepare(stmthpp, errhpp,…);

绑定输入变量: OCIBindByPos(stmtp &hBind, errhp,…);

绑定输出变量: OCIDefineByPos(stmthpp, &bhp1,

errhpp,…);

获得 SQL 语句类型: OCIAttrGet ((dvoid *)stmthpp,

(ub4)OCI_HTYPE_STMT,…);

执行 SQL 语句: OCIStmtExecute(svchpp, stmthpp,…);

释放一个会话: OCISessionRelease();

删除到数据源的访问 : OCIServerDetach(servhpp, errhpp, OCI_DEFAULT);

释放句柄: OCIHandleFree((dvoid *) stmthpp, OCI_HTYPE_STMT);

二、实践:

我把程序贴到该文章的第二篇中,以下针对应用得以分析并进行说明。

三、基本理论:

1 、创建 OCI 环境即创建和初始化 OCI 工作环境,其他的 OCI 函数需要 OCI 环境才能执行。

2 、需要申请的句柄类型:

OCI 环境句柄: OCI_HTYPE_ENV— 它定义所有 OCI

函数的环境调用环境,是其他句柄的父句柄。 ( 由 OCIEnvInit 或 OCIEnvCreate 生成 ) 。

错误句柄: OCI_HTYPE_ERROR— 作为一些 OCI 函数的参数,用来记录这些

OCI 函数操作过程中所产生的错误,当有错误发生时,可用 COIErrorGet()

来读取错误句柄 中记录的错误信息。

服务器环境句柄: OCI_HTYPE_SVCCTX— 定义 OCI

调用的服务器操作环境,它包含服务器、用户会话和事务三种句柄。

服务器句柄: OCI_HTYPE_SERVER— 标识数据源,它转换为与服务器的物理连接。

用户会话句柄: OCI_HTYPE_SESSION— 定义用户角色和权限及 OCI 调用的执行环境。

事务句柄: OCI_HTYPE_TRANS— 定义执行 SQL 操作的事务环境,事务环境中包含用户的会话状态信息。

语句句柄: OCI_HTYPE_STMT— 是一个标识 SQL 语句或 PL/SQL 块,以及其相关属性的环境。

Bind/Define 句柄:属于语句句柄的子句柄,由 OCI 库隐式自动生成。用户不需要自己再申请, OCI 输入变量存储在

bind 句柄中,输出变量存储在定义句柄中。

3 、句柄属性包括:

服务器环境句柄属性: (OCI_HTYPE_SVCCTX)

OCI_ATTR_SERVER— 设置 / 读取服务环境的服务器环境属性

OCI_ATTR_SESSION— 设置 / 读取服务环境的会话认证环境属性

OCI_ATTR_TRANS— 设置 / 读取服务环境的事务环境属性

用户会话句柄属性: (OCI_HTYPE_SESSION)

OCI_ATTR_USERNAME— 设置会话认证所使用的用户名

OCI_ATTR_PASSWORD— 设置会话认证所使用的用户口令

服务器句柄: (OCI_HTYPE_SEVER)

OCI_ATTR_NOBLOCKING_MODE— 设置 / 读取服务器连接: =TRUE 时服务器连接设置为非阻塞方式

语句句柄: (OCI_HTYPE_STMT)

OCI_ATTR_ROW_COUNT— 只读,为当前已处理的行数,其 default=1

OCI_ATTR_STMT_TYPE— 读取当前 SQL 语句的类型:

4 、 OCI 函数返回值:

OCI_SUCCESS – 函数执行成功 (=0)

OCI_SUCCESS_WITH_INFO – 执行成功,但有诊断消息返回,可能是警告信息

OCI_NO_DATA— 函数执行完成,但没有其他数据

OCI_ERROR— 函数执行错误

OCI_INVALID_HANDLE— 传递给函数的参数为无效句柄,或传回的句柄无效

OCI_NEED_DATA— 需要应用程序提供运行时刻的数据

OCI_CONTINUE— 回调函数返回代码,说明回调函数需要 OCI 库恢复其正常的处理操作

OCI_STILL_EXECUTING— 服务环境建立在非阻塞模式, OCI 函数调用正在执行中。

5 、 OCI 函数设置的模式有:

OCI_DEFUALT: 使用 OCI 默认的环境

OCI_THREADED :线程环境下使用 OCI

OCI_OBJECT :对象模式

OCI_SHARED :共享模式

OCI_EVENTS

OCI_NO_UCB

OCI_ENV_NO_MUTEX :非互斥访问模式

6 、 OCI 重定义数据类型

typedef unsigned char ub1;

typedef unsigned short ub2;

typedef unsigned int ub4;

typedef signed char sb1;

typedef signed short sb2;

typedef signed int sb4;

typedef ub4 duword;

typedef sb4 dsword;

typedef dsword dword;

oci函数的详细介绍 和应用实例 OCI 连接过程比较复杂,除了分配设置各个基本句柄外,还要明确彼此之间的联系,大致流程如下: 创建环境句柄OCIEnvCreate(&envhp;, …); 创建一个指定环境的错误句柄OCIHandleAlloc((dvoid *)envhp, (dvoid **)&errhp;,…); 创建一个指定环境的服务器句柄OCIHandleAlloc((dvoid *)envhp, (dvoid **)&servhp;,…); 建立到数据源的访问路径 : OCIServerAttach(servhpp, errhpp,…); 创建一个指定环境的服务上下文句柄: (void) OCIHandleAlloc((dvoid *)envhpp,…); 为指定的句柄及描述符设置特定的属性: (void) OCIAttrSet((dvoid *)svchpp,…); 创建一个指定环境的用户连接句柄: (void) OCIHandleAlloc((dvoid *)envhpp,…); 为用户连接句柄设置登录名及密码: (void) OCIAttrSet((dvoid *)usrhpp,…); 认证用户建立一个会话连接: OCISessionBegin(svchpp, errhpp,…); 创建一个句子句柄OCIHandleAlloc((dvoid *)envhpp,…);s 准备 SQL 语句: OCIStmtPrepare(stmthpp, errhpp,…); 绑定输入变量: OCIBindByPos(stmtp &hBind;, errhp,…); 绑定输出变量: OCIDefineByPos(stmthpp, &bhp1;, errhpp,…); 获得 SQL 语句类型: OCIAttrGet ((dvoid *)stmthpp, (ub4)OCI_HTYPE_STMT,…); 执行 SQL 语句: OCIStmtExecute(svchpp, stmthpp,…); 释放一个会话: OCISessionEnd(); 删除到数据源的访问 : OCIServerDetach(servhpp, errhpp, OCI_DEFAULT); 释放句柄OCIHandleFree((dvoid *) stmthpp, OCI_HTYPE_STMT);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值