Pro*C  OCI …

 

Pro*C  OCI  OCCI  这三种都是C/C++访问数据库的手段。


Pro*C

      内嵌SQL,预编译后把内嵌SQL处理为ORACLE标准运行库的调用,然后再象编译一般的C程序一样进行编译、连接、运行。
1.proc XXX.pc
2.gcc/g++ XXX.c –lclntsh

(PRO*C的预编译,也可直接MAKEFILE搞定)

 

OCI/OCCI

     oracle提供的访问oracle数据库的API,比较繁琐,但是完全符合C/C++语言的访问流程,清晰,便于理解,调试。

OCI:Oracle Call Interface ;(C语言实现)
OCCI:Oracle C++ Call Interface;(C++语言实现)

 

 

OCI使用步骤大致介绍

原作者:hoarn  博客地址:http://blog.sina.com.cn/u/1422583511

 

     OCI(Oracle Call Inte***ce)是由头文件和库函数等组成的一套Oracle数据库应用程序编程接口工具,OCI程序实质上就是用高级语言写的程序,其特点是内部含有对OCI子函数库的调用。
     OCI程序对开发环境的要求相对较低,只要有C语言的OCI开发工具包和C编译器就可以,程序设计相比PRO*C复杂了点。

 

1、创建和初始化OCI环境
     首先要在源程序中包含OCI头文件:#include <oci.h> 
     OCI环境即OCI函数的工作环境,在调用其他函数之前必须先调用OCIInitialize()和OCIEnvInit()函数创建和初始化OCI环境,其他OCI函数要在这个环境中才能执行。
先定义变量:
OCIEnv**   m_envhp;
OCIError*  m_errhp;
OCIServer* m_srvhp;
OCISvcCtx* m_svchp;
OCIStmt *  m_stmthp;

OCIInitialize(
               (ub4) OCI_DEFAULT,
               (dvoid *)0,
               (dvoid * (*)(dvoid *, size_t))0,
               (dvoid * (*)(dvoid *, dvoid *, size_t))0,
               (void (*)(dvoid *, dvoid *))0
              );

OCIEnvInit(
            (OCIEnv **)&m_envhp,
            OCI_DEFAULT, (size_t)0,
            (dvoid **)0
           );

其中m_envhp为输出参数,是一个指向OCI环境句柄的指针,OCI_DEFAULT 是OCI环境的初始化模式。OCIEnvInit()函数中的size_t类型变量为分配给用户的内存数量,dvoid **类型变量指向用户的内存区域,该区域的大小等于size_t类型变量。
OCI函数中,大量使用OCI定义的数据类型和宏,其定义可参考$ORACLE_HOME/rdbms/demo目录下的oci.h头文件。

 

2、申请句柄
     句柄是指向OCI库所分配的内存区域的指针,该内存区域中的数据由OCI库维护,应用程序可通过句柄访问其中的数据。下面是应用程序中最常用的几个句柄:
OCIHandleAlloc(
                (dvoid *)m_envhp,
                (dvoid **)&m_errhp,
                 OCI_HTYPE_ERROR,
                (size_t)0,
                (dvoid **)0
               );

OCIHandleAlloc(
                (dvoid *)m_envhp,
                (dvoid **)&m_srvhp,
                OCI_HTYPE_SERVER,
                (size_t)0,
                (dvoid **)0
              );

OCIHandleAlloc(
                (dvoid *)m_envhp,
                (dvoid **)&m_svchp,
                 OCI_HTYPE_SVCCTX,
                (size_t) 0,
                (dvoid **)0
              );

OCIHandleAlloc(
                (dvoid *)m_envhp,
                (dvoid **)&m_stmthp,
                 OCI_HTYPE_STMT,
                (size_t)0,
                (dvoid **)0
               );

其中m_errhp为新申请的句柄,m_envhp为它的父环境句柄,OCI_HTYPE_ERROR为句柄类型,表示这是一个错误报告句柄,OCI_HTYPE_SERVER表示服务器句柄,OCI_HTYPE_SVCCTX表示服务环境句柄,OCI_HTYPE_STMT表示语句句柄。

     存储在句柄中的数据称为句柄属性,所有OCI句柄都具有属性,可以调用OCIAttrGet()和OCIAttrSet()函数来读取、设置句柄属性。

 

3、连接服务器建立会话
首先调用
OCIServerAttach(m_srvhp, m_errhp, (text *)"", strlen(""), OCI_DEFAULT);
函数建立与指定服务器的连接,text *类型变量为空,表示连接默认数据库服务,OCI_DEFAULT表示应用程序的操作模式为阻塞模式,在这种方式下,只有当OCI调用完成后才将控制权返回给客户端应用程序。

然后调用
OCILogon(m_envhp,m_errhp, &m_svchp, (text*)m_szUser,strlen(m_szUser), (text*)m_szPassword, strlen(m_szPassword), (text*)m_szDbName, strlen(m_szDbName));
建立数据库会话。此函数隐含申请服务器句柄和用户会话句柄,登录后,句柄是只读的,不能再设置句柄属性。

 

4、执行SQL语句并处理数据
将要执行的SQL语句copy到szSqlStr字符串中:
snprintf( szSqlStr, sizeof(szSqlStr), "select PASSWORD from USERS where USERNAME=’chen’ ");
执行下列语句:

OCIStmtPrepare(m_stmthp, m_errhp, (text*)szSqlStr, (ub4) strlen(szSqlStr), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT); //准备SQL语句

OCIDefine *defnp0 = (OCIDefine *) 0; //定义输出变量

OCIDefineByPos( m_stmthp, &defnp0, m_errhp, 1, (dvoid *)szUSERNAME, 100, SQLT_STR, (dvoid *) 0, (ub2 *)0, (ub2 *)0, OCI_DEFAULT); //绑定变量

OCIStmtExecute( m_svchp, m_stmthp, m_errhp, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL,(OCISnapshot *) NULL, (ub4) OCI_DEFAULT); //执行SQL语句

 

5、结束会话断开数据库连接
OCILogoff( m_svchp, m_errhp );

 

6、断开与数据源的连接,释放句柄
OCIServerDetach( m_srvhp, m_errhp, OCI_DEFAULT ); //断开与数据源的连接
OCIHandleFree((dvoid *) m_stmthp, OCI_HTYPE_STMT); //释放句柄
OCIHandleFree((dvoid *) m_svchp, OCI_HTYPE_SVCCTX);
OCIHandleFree((dvoid *) m_srvhp, OCI_HTYPE_SERVER);
OCIHandleFree((dvoid *) m_errhp, OCI_HTYPE_ERROR)

3.7生成可执行文件(两种方法)
(1)同普通的C程序:
   gcc -o exampled –I. –I$(ORACLE_HOME)/precomp/public example.c

(2)利用Oracle自带的Make文件:
首先将$ORACLE_HOME/rdbms/demo/demo_rdbms.mk文件copy到OCI源程序所在的目录,将源文件编译为目标文件:
#gcc –c example.o -I$(ORACLE_HOME)/rdbms/demo -I$(ORACLE_HOME)/network/public -I$(ORACLE_HOME)/rdbms/public/ example.c
然后用命令:#make -f demo_rdbms.mk build OBJ*=**ample.o EXE=exampled,exampled就为生成的可执行文件

 

 

OCI常用函数说明:

原作者:hoarn  博客地址:http://blog.sina.com.cn/u/1422583511

 

一、初始化OCI程序环境。
OCI8使用OCIInitialize函数来初始化OCI。这是使用OCI8与数据库建立会话必须的一步;同时,必须是第一步。如果成功,则返回0。
函数原型:sword OCIInitialize (ub4 mode,CONST dvoid *ctxp,CONST dvoid *(*malocfp) (/* dvoid *ctxp,size_t size _* /),
CONST dvoid *(*ralocfp)(/*_ dvoid *ctxp,dvoid *memptr,size_t newsize _* /),
CONST void (*mfreefp)(/*_ dvoid *ctxp,dvoid *memptr _* /))
参数说明:
mode——详细说明OCI初始化(Initialize)模式(mode)。它的取值如下:
OCI_DEFAULT——缺省模式;
OCI_THREADED——多线程模式;在该模式下,各并发处理中不为用户所见的内在数据结构受各自线程的保护,而不受别的线程干扰;
OCI_OBJECT——使用目标特性;
OCI_SHARED——使用共享内存;
OCI_EVENTS——
Mode参数可以拥有多个值,以“|”符号分隔各取值项。
*Ctxp——用户定义的内存回调程序;默认为0
*(*malocfp)——用户定义的内存分配程序;默认为0
*(*ralocfp)——重新分配内存程序;默认为0
*memptr 是指向内存块的指针;
*mfreefp——用户定义的内存释放程序;默认为0
该函数使用举例如下:
OCIInitialize((ub4) OCI_THREADED | OCI_OBJECT,
(dvoid *)0,(dvoid *(*)(dvoid *, size_t)) 0,
(dvoid * (*)(dvoid *,dvoid *,size_t))0,
(void (*)(dvoid *,dvoid *)) 0 )
注意!OCIEnvCreate() 可以代替OCIInitialize() 和OCIEnvInit()


二、 初始化OCI环境句柄。
在初始化OCI程序环境以后,使用OCIEnvInit来初始化OCI的环境句柄,该函数成功返回0。
函数原型:sword OCIEnvInit(OCIEnv **envhpp,
ub4 mode,
size_t xtramemsz,
dvoid **usrmempp )
参数说明:
**envhpp——指向环境句柄的指针;
mode——指定初始化环境句柄的模式,其取值如下:
OCI_DEFAULT——缺省模式;在缺省模式下,OCI库始终互斥各环境句柄;
OCI_NO_MUTEX——非互斥模式;在该模式下,OCI库各环境句柄并不互斥,所有的掉用都使用同一个环境句柄,并且只能有一个环境句柄起作用。
OCI_ENV_NO_UCB——禁止回滚模式;该模式用以禁止在环境句柄初始化过程中的动态CALL_BACK函数掉用;
Xtramemsz——指定在该环境句柄生存期内分配内存的数量;
**usrmempp——指向Xtramemsz参数的指针;usermempp参数是函数返回值;
该函数使用举例如下:
应用例子:OCIEnvInit((OCIEnv **) envhp,
(ub4) OCI_DEFAULT,
(size_t) 0,(dvoid **) 0)


三、 分配各OCI句柄。
一个OCI连接在建立前,还需要将所需要的句柄一一分配成功,在OCI8里,使用函数OCIHandleAlloc来分配各句柄,成功返回0。
函数原型:sword OCIHandleAlloc(CONST dvoid *parenth,
dvoid **hndlpp,
ub4 type,
size_t xtramem_sz,
dvoid **usrmempp )
参数说明:
*parenth——已初始化后的环境句柄;
**hndlpp——函数执行成功后,返回的一个OCI句柄;该返回值的具体含义由type参数来决定;
type——参数hndlpp的返回值的类型;其常用取值如下:
OCI_HTYPE_SVCCTX——返回一个服务类型的句柄;
OCI_HTYPE_ERROR——返回一个错误类型的句柄;
OCI_HTYPE_SESSION——返回一个会话类型的句柄;
OCI_HTYPE_SERVER——返回一个服务器类型的句柄;
OCI_HTYPE_STMT——返回一个陈述类型的句柄;
其中,陈述类型的句柄是在创建与数据库会话成功后,将要对数据库进行操作时分配的,其余类型的句柄是在环境句柄初始化后分配的;
xtramem_sz——指定在该句柄生存期内分配内存的数量;
**usrmempp——指向xtramem_sz参数的指针,由函数返回;
该函数使用举例如下:OCIHandleAlloc((dvoid *) *envhp,
(dvoid **) errhp,
(ub4) OCI_HTYPE_ERROR,
(size_t) 0,
(dvoid **) 0)


四、 为OCI操作数据源创建存储路径
(以给定的方式设置服务器连接指针的参数)。
分配各OCI句柄后,还需要做的工作是为OCI操作数据源创建存储路径,并将各项参数设置到相应的句柄中,这项工作由函数OCIServerAttach和OCIAttrSet来实现。成功,返回0。
函数原型:sword OCIServerAttach(OCIServer *srvhp,
OCIError *errhp,
CONST text *dblink,
sb4 dblink_len,
ub4 mode )
参数说明:
*srvhp——已分配成功的服务器句柄;
*errhp——已分配成功的错误类型句柄;若该函数执行出错,则该参数承载出错的原因;
*dblink——登陆数据库的实例名;
dblink_len——参数*dblink字符串的长度;
mode——指定不同操作的模式。现在只有一种模式可选:OCI_DEFAULT。
该函数使用举例如下:OCIServerAttach(srvhp, errhp,
(text *) cstring,
(sb4) strlen((char *)cstring), (ub4) OCI_DEFAULT))
函数原型:sword OCIAttrGet (CONST dvoid *trgthndlp,
ub4 trghndltyp,
dvoid *attributep,
ub4 *sizep,
ub4 attrtype,
OCIError *errhp )
参数说明:
*trgthndlp——需要设置的句柄,该句柄在这之前已分配成功;该参数由trghndltyp参数决定;
trghndltyp——参数trgthndlp的类型,其取值参见OCIHandleAlloc函数说明中的type参数说明;
*attributep——设置参数trgthndlp的值;
*sizep——attributep参数指向的字符串长度;
attrtype——参数attributep的类型;其取值如下:
OCI_ATTR_SERVER——服务器类型;
OCI_ATTR_USERNAME——用户名类型
OCI_ATTR_PASSWORD——用户密码类型
OCI_ATTR_SESSION——会话类型;
*errhp——已分配成功的错误类型句柄;若该函数执行出错,则该参数承载出错的原因;
该函数使用举例如下:OCIAttrSet((dvoid *) svchp,
(ub4) OCI_HTYPE_SVCCTX,
(dvoid *) srvhp,
(ub4) 0,
(ub4) OCI_ATTR_SERVER,
errhp))
(注:此时该函数的意思是将服务器句柄设置到服务句柄中,其类型为服务器类型)
说明:在登陆数据库前以给定的方式设置服务器连接指针的参数时,attrtype参数的所有类型都需要设置到服务句柄中。设置的步骤为:先将服务器句柄设置到服务句柄中,然后将用户名、密码设置到会话句柄中,在调用OCISessionBegin函数成功后,再将会话句柄设置到服务句柄中。


五、 创建并开始与数据库的会话
创建和开始与数据库的会话使用函数OCISessionBegin来实现,其目的是建立与数据库的会话连接;函数成功,返回0。
函数原型:sword OCISessionBegin (OCISvcCtx *svchp,
OCIError *errhp,
OCISession *authp,
ub4 credt,
ub4 mode))
参数说明:
*svchp——已分配并设置成功的服务句柄;
*errhp——已分配成功的错误类型句柄;若该函数执行出错,则该参数承载出错的原因;
*authp——已分配并设置了用户名、密码的会话句柄;
credt——建立用户会话的类型;其取值如下:
OCI_CRED_RDBMS——需要使用用户名和密码来建立会话;
OCI_CRED_EXT——不需要使用用户名和密码来建立会话;
mode——操作的模式;其取值如下:
OCI_DEFAULT——缺省模式;在该模式下只支持一个会话句柄;
OCI_MIGRATE——移动会话模式;在该模式下,新的会话连接会以不同的会话句柄返回;使用该模式创建新的会话时,必须已存在一个不可移动会话模式的会话连接。也就是说,一个移动会话模式的会话连接必须有一个不可移动模式的连接作为父连接;
OCI_SYSDBA——在该模式下,会鉴别用户是否以SYSDBA形式对数据库进行访问;
OCI_SYSOPER——在该模式下,会鉴别用户是否以SYSOPER形式对数据库进行访问;
OCI_PRELIM_AUTH——这种模式和OCI_SYSDBA、OCI_SYSOPER一起使用,作为某些访问任务的鉴别;
该函数使用举例如下:OCISessionBegin(svchp,
errhp,
authp,
OCI_CRED_RDBMS,
OCI_DEFAULT)


六、 取得errhp承载的错误原因。
若某函数执行出错,则可以使用函数OCIErrorGet来取得错误原因,从而能得到某些提示。
函数原型:sword OCIErrorGet (dvoid *hndlp,
ub4 recordno,
text *sqlstate,
sb4 *errcodep,
text *bufp,
ub4 bufsiz,
ub4 type )
参数说明:
*hndlp——错误类型句柄errhp;
recordno——错误查找的原始位置,从1开始,其缺省值为1;
*sqlstate——OCI8不支持,缺省值为NULL;
*errcodep——ORACLE错误返回代码,由函数返回;初始值可以为(sb4)0;
*bufp——错误信息提示,由函数以字符串形式返回;
bufsiz——bufp参数原始字符串长度;
type——句柄类型;其取值为OCI_HTYPE_ERR或着为OCI_HTYPE_ENV;缺省值为OCI_HTYPE_ERR;
该函数使用举例如下:OCIErrorGet((dvoid *) errhp,
(ub4) 1,
(text *) NULL,
&errcode,
(text *)msgbuf,
(ub4) sizeof(msgbuf),
(ub4) OCI_HTYPE_ERROR)


七、 准备执行
用户定义的SQL或PL/SQL陈述语句。
在执行SQL或PL/SQL语句前,需要对该语句执行分析、出错检查,并和陈述句柄棒定起来,使用函数OCIStmtPrepare来进行这一系列操作。该函数在执行陈述语句前必须使用;成功,返回0;
函数原型:sword OCIStmtPrepare ( OCIStmt *stmtp,
OCIError *errhp,
CONST text *stmt,
ub4 stmt_len,
ub4 language,
ub4 mode)
参数说明:
*stmtp——已分配成功的陈述句柄;
*errhp——已分配成功的错误类型句柄;若该函数执行出错,则该参数承载出错的原因;
*stmt——用户定义的需要执行的SQL或PL/SQL陈述语句;
stmt_len——用户定义的需要执行的陈述语句的长度;该参数的值不能为0;
language——语法模式;声明是本地语法,还是V7模式语法。其取值如下:
OCI_V7_SYNTAX——ORACLE的V7分析语法;
OCI_NTV_SYNTAX——语法依赖于服务器的版本;
mode——模式;其缺省值为OCI_DEFAULT;
该函数使用举例如下:OCIStmtPrepare(stmthp,
errhp,
sqlcommand,
(ub4)strlen((char *)sqlcommand),
(ub4) OCI_NTV_SYNTAX,
(ub4) OCI_DEFAULT)


八、 定义输出变量。
OCI执行陈述语句后,将所选择的变量值返回输出,此时需有用户定义的地址空间来容纳这些返回值。使用函数OCIDefineByPos通过在陈述语句中标志某变量在用户定义的变量集合中的位置来定义变量;若该函数执行成功,返回0。
函数原型:sword OCIDefineByPos (OCIStmt *stmtp,
OCIDefine **defnpp,
OCIError *errhp,
ub4 position,
dvoid *valuep,
sb4 value_sz,
ub2 dty,
dvoid *indp,
ub2 *rlenp,
ub2 *rcodep,
ub4 mode )
参数说明:
*stmtp——用以进行查询的陈述语句句柄;该句柄必须是已经分配成功的句柄;
**defnpp——用户定义的变量集合的指针;该参数指针从下标0开始,依次递增一个数组单元;
*errhp——已分配成功的错误类型句柄;若该函数执行出错,则该参数承载出错的原因;
position——需要定义的变量在定义句柄的列表中的位置,从1开始;例如:
SELECT empno, ssn, mgrno FROM employees;
则empno的position值为1,ssn的position的值为2,mgrno的position值为3;以此类推。
*valuep——需要定义的变量的在执行成功后的存储地址;如果提取出来的数据有多项,则该参数可以使用数组;
value_sz——valuep参数的指向的存储地址空间的长度;
dty——需要定义的变量的数据类型;SQLT_STR表示该变量是个字符串变量;SQLT_INT则表示该变量是个整型变量;
*indp——变量或数组指示器,默认为0;
*rlenp——变量或数组长度指示器,默认为0;
*rcodep——即将提取的变量的值指示器,默认为0;
mode——变量提取模式。其取值为OCI_DEFAULT或OCI_DYNAMIC_FETCH;OCI_DYNAMIC_FETCH用于在提取资料过程中,需要动态资料的时候,此时必须用CIDefineDynamic函数建立一个回调函数用以提取数据;这种情况下,valuep和value_sz参数可以忽略;
该函数使用举例如下:OCIDefineByPos(stmthp, &dfnhp[4],
errhp, (ub4) 5,
(dvoid *) &No[0],
(sb4) sizeof(No[0]),
(ub2) SQLT_INT,
(dvoid *) 0,
(ub2 *) 0,
(ub2 *) 0,
(ub4) OCI_DEFAULT)
补充说明:如果输出变量是多行资料,则valuep参数应该为一个用户定义了大小的静态数组的初始地址,其大小为输出变量的行数与该变量自身大小的乘积。此时,在函数后面还需要使用另一个函数OCIDefineArrayOfStruct来定义该数组。函数OCIDefineArrayOfStruct说明如下:
函数原形:sword OCIDefineArrayOfStruct(OCIDefine *defnp,
OCIError *errhp,
ub4 pvskip,
ub4 indskip,
ub4 rlskip,
ub4 rcskip )
参数说明:
*defnp——从函数OCIDefineByPos返回的对应该变量的定义句柄,对应于OCIDefineByPos函数的第二项参数defnpp;
*errhp——已分配成功的错误类型句柄;若该函数执行出错,则该参数承载出错的原因;
pvskip——从本条记录中该变量的存储地址的到下条记录中该变量的存储地址之间的大小;也就是定义的一条记录的存储空间的大小;
indskip——默认为0;
rlskip——默认为0;
rcskip——默认为0;
该函数使用举例说明如下(对应于函数OCIDefineByPos的例子):
OCIDefineArrayOfStruct(dfnhp[4],
errhp,
sizeof(No[0]),
0,0,0)


九、 定义输入变量
OCI在执行陈述语句时,有时需要向该语句传递输入值,OCI8通过函数OCIBindByPos或OCIBindByName来实现该功能,OCIBindByPos将需要输入的变量与与其对应的参数值的位置绑定起来,从而实现向陈述语句中传递值的效果,而OCIBindByName则是通过绑定相应的变量名称来实现输入值的传递。
函数原型:sword OCIBindByPos ( OCIStmt *stmtp,
OCIBind **bindpp,
OCIError *errhp,
ub4 position,
dvoid *valuep,
sb4 value_sz,
ub2 dty,
dvoid *indp,
ub2 *alenp,
ub2 *rcodep,
ub4 maxarr_len,
ub4 *curelep,
ub4 mode )
参数说明:
*stmtp——用以进行查询的陈述语句句柄;该句柄必须是已经分配成功的句柄;
**bindpp——用户定义的传入值集合的指针;该参数指针从下标0开始,依次递增一个数组单元;
*errhp——已分配成功的错误类型句柄;若该函数执行出错,则该参数承载出错的原因;
position——需要绑定的该变量在陈述语句的列表中的位置,从1开始,依次递增;
*valuep——需要绑定的传入值的存储地址;
value_sz——valuep参数的指向的存储地址空间的长度;
dty——需要绑定的变量的数据类型;SQLT_STR表示该变量是个字符串变量;SQLT_INT则表示该变量是个整型变量;
*indp——变量或数组指示器,默认为0;
*alenp——变量或数组长度指示器,默认为0;
*rcodep——即将提取的变量的值指示器,默认为0;
maxarr_len——dyt参数的最大可能取值的数目,在非PL/SQL语句中该差数无效果;默认值为0;
*curelep——对应与maxarr_len,表示dyt参数取值的实际数目;默认值为0;
mode——变量提取模式。其取值为OCI_DEFAULT或OCI_DATA_AT_EXEC;当使用OCI_DATA_AT_EXEC时,value_sz表示在该陈述语句执行过程中可以使用的传入的该项值的最大存储长度,此时需要动态绑定该传入值;一般来说,mode的取值都为OCI_DEFAULT;
该函数使用举例如下:OCIBindByPos(stmthp, &bndhp[3],
errhp, (ub4) 4,
(dvoid *) register_number,
(sb4) nLen, SQLT_STR,
(dvoid *) 0, (ub2 *)0,
(ub2 *)0,
(ub4) 0, (ub4 *) 0,
(ub4) OCI_DEFAULT)
函数原型:sword OCIBindByName ( OCIStmt *stmtp,
OCIBind **bindpp,
OCIError *errhp,
CONST text *placeholder,
sb4 placeh_len,
dvoid *valuep,
sb4 value_sz,
ub2 dty,
dvoid *indp,
ub2 *alenp,
ub2 *rcodep,
ub4 maxarr_len,
ub4 *curelep,
ub4 mode )
参数说明:
*stmtp——用以进行查询的陈述语句句柄;该句柄必须是已经分配成功的句柄;
**bindpp——用户定义的传入值集合的指针;该参数指针从下标0开始,依次递增一个数组单元;
*errhp——已分配成功的错误类型句柄;若该函数执行出错,则该参数承载出错的原因;
*placeholder——需要绑定的该变量在陈述语句中的占位符;
placeh_len——palceholder参数的长度;
*valuep——指向需要绑定的该变量的传入值的地址;
value_sz——valuep参数存储的变量值的位组长度;
dty——需要绑定的变量的数据类型;SQLT_STR表示该变量是个字符串变量;SQLT_INT则表示该变量是个整型变量;
*indp——变量或数组指示器,默认为0;
*alenp——变量或数组长度指示器,默认为0;
*rcodep——即将提取的变量的值指示器,默认为0;
maxarr_len——dyt参数的最大可能取值的数目,在非PL/SQL语句中该差数无效果;默认值为0;
*curelep——对应与maxarr_len,表示dyt参数取值的实际数目;默认值为0;
mode——变量提取模式。其取值为OCI_DEFAULT或OCI_DATA_AT_EXEC;当使用OCI_DATA_AT_EXEC时,value_sz表示在该陈述语句执行过程中可以使用的传入的该项值的最大存储长度,此时需要动态绑定该传入值;一般来说,mode的取值都为OCI_DEFAULT;
该函数使用举例如下:OCIBindByName(stmthp, &bndhp[1], errhp,
(text *) ":field1",
(sb4) strlen((char *) ":phone_number"),
(dvoid *) & to_field1,
(sb4) sizeof(phone_number),
SQLT_STR,
(dvoid *) 0, (ub2 *)0,
(ub2 *)0,(ub4) 0, (ub4 *) 0,
(ub4) OCI_DEFAULT)
补充说明:如果输入变量是多行资料,则valuep参数应该为一个用户定义了大小的静态数组的初始地址,其大小为输入变量的行数与该变量自身大小的乘积。此时,在函数后面还需要使用另一个函数OCIBindArrayOfStruct来定义该数组。函数OCIBindArrayOfStruct说明如下:
函数原型:sword OCIBindArrayOfStruct ( OCIBind *bindp,
OCIError *errhp,
ub4 pvskip,
ub4 indskip,
ub4 alskip,
ub4 rcskip )
参数说明:
*bindp——从函数OCIBindByPos或OCIBindByName返回的对应该变量的绑定句柄,对应于函数OCIBindByPos或OCIBindByName的第二项参数bindpp;
*errhp——已分配成功的错误类型句柄;若该函数执行出错,则该参数承载出错的原因;
pvskip——从本条记录中该变量的存储地址的到下条记录中该变量的存储地址之间的大小;也就是定义的一条记录的存储空间的大小;
indskip——默认为0;
rlskip——默认为0;
rcskip——默认为0;
该函数使用举例如下:OCIBindArrayOfStruct(bndhp[N],
errhp,
sizeof(record_array[0]),
indsk[N],
rlsk[N],
rcsk[N])


十、 执行陈述语句。
在执行语句分析完成,并且变量定义或绑定完成后,便可以执行该陈述句柄,从而实现陈述语句中的SQL语句能完成的功能。使用函数OCIStmtExecute来执行该陈述句柄。执行成功,返回0;
函数原型:sword OCIStmtExecute ( OCISvcCtx *svchp,
OCIStmt *stmtp,
OCIError *errhp,
ub4 iters,
ub4 rowoff,
CONST OCISnapshot *snap_in,
OCISnapshot *snap_out,
ub4 mode)
参数说明:
*svchp——已分配并设置成功的服务句柄;
*stmtp——指向需要执行的陈述语句的句柄;
*errhp——已分配成功的错误类型句柄;若该函数执行出错,则该参数承载出错的原因;
iters——对于非选择语句来说,该函数执行次数等于iters减去rowoff的值;对于选择语句来说,如果iters不为0,则该函数在执行前必须有定义句柄(即需要定义位址空间来存储select出来的变量值),而函数会预先提取出多于iters条记录(如果可提取记录条数大于iters的话),将其中iters条正式提取出来;如果事先并不知道有多少条记录会被提取,则将iters的值置为0;在非选择语句中,若iters的值为0,则函数返回错误;
rowoff——函数执行时,输入变量在绑定的变量数组的开始位置。用于多行记录的修改或插入、删除;比如,定义的绑定变量为array[100],执行该函数时,iters的值为50,rowoff的值为10,则表示从array[10]开始提取传入值,而执行的次数则是50-10 = 40(次);
*snap_in——可选参数。默认值为0;
*snap_out——可选参数。默认值为0;
mode——执行模式;有四种执行模式:
OCI_DEFAULT——缺省模式,在该模式下,总是隐式返回选择选择语句的有关描述信息;
OCI_DESCRIBE_ONLY——在该模式下,陈述句柄并不被执行,但是它会返回可提取记录的条数;
OCI_COMMIT_ON_SUCCESS——在该模式下,如若函数执行成功,则当前的处理马上会自动提交;
OCI_EXACT_FETCH——该模式用于当前程序很明确的清楚有多少条记录会被提取出来;并且,使用该模式前必须要有定义句柄;
该函数的使用举例如下:OCIStmtExecute(svchp, stmthp, errhp,
(ub4) nCount, (ub4) 0,
(CONST OCISnapshot*) 0,
(OCISnapshot*) 0,
(ub4) OCI_DEFAULT)
另外,还可以使用函数OCIStmtFetch来提取固定数目的记录,其函数使用说明如下:
函数原型:sword OCIStmtFetch ( OCIStmt *stmtp,
OCIError *errhp,
ub4 nrows,
ub2 orientation,
ub4 mode )
参数说明:
*stmtp——需要执行的陈述句柄;
*errhp——已分配成功的错误类型句柄;若该函数执行出错,则该参数承载出错的原因;
nrows——需要提取的记录的条数;
orientation——该参数只有唯一一个缺省值:OCI_FETCH_NEXT;
mode——默认为OCI_DEFAULT;
该函数使用举例如下:sword OCIStmtFetch (stmtp,
errhp,
rows_number,
OCI_FETCH_NEXT,
OCI_DEFAULT)
该函数成功执行,而无数据时,返回OCI_NO_DATA;


十一、事务提交。
在执行陈述句柄后,有的语句如insert、delete等需要提交当前事务,从而真正实现insert、delete等功能。OCI8使用函数OCITransCommit来实现这一功能。
函数原型:sword OCITransCommit ( OCISvcCtx *svchp,
OCIError *errhp,
ub4 flags )
参数说明:
*svchp——已分配并设置成功的服务句柄;其值等于于OCIStmtExecute函数的srchp参数值。
*errhp——已分配成功的错误类型句柄;若该函数执行出错,则该参数承载出错的原因;
flags——提交标志。默认为0;
该函数使用举例如下:OCITransCommit(svchp, errhp, (ub4) 0)


十二、事务回滚。
在执行完陈述语句后,若需要取消当前执行的操作,则需要回滚当前事务。OCI8使用函数OCITransRollback来完成该功能。
函数原型:sword OCITransRollback(dvoid *svchp,
OCIError *errhp,
ub4 flags )
参数说明:
*svchp——需要回滚当前事务的服务句柄;其值等于于OCIStmtExecute函数的srchp参数值。
*errhp——已分配成功的错误类型句柄;若该函数执行出错,则该参数承载出错的原因;
flags——回滚标志。目前只有一个唯一的取值得:OCI_DEFAULT;
该函数使用举例如下:OCITransRollback(svchp,
errhp,
OCI_DEFAULT)


十三、断开与数据库的连接
断开与数据库的连接需要进行下面一系列工作:结束当前会话、断开与数据库连接服务、释放分配的各个句柄。下面分别说明各项工作所使用的oci函数。
结束当前会话:如果要断开与数据库的连接,则需要先结束当前会话,使用函数OCISessionEnd来完成该功能。执行成功,返回0
函数原型:sword OCISessionEnd(OCISvcCtx *svchp,
OCIError *errhp,
OCISession *authp,
ub4 mode)
参数说明:
*svchp——需要断开的服务句柄;
*errhp——已分配成功的错误类型句柄;若该函数执行出错,则该参数承载出错的原因;
*authp——会话句柄;
mode——会话结束模式。目前只有一种模式:OCI_DEFAULT;
该函数使用举例如下:OCISessionEnd(svchp,
errhp,
authp,
(ub4) 0)
断开与数据库的连接服务:当前会话结束后,需要断开与服务器的连接,结束用户对数据库的操作。OCI8使用函数OCIServerDetach来完成该任务。执行成功,返回0;
函数原型:sword OCIServerDetach(OCIServer *srvhp,
OCIError *errhp,
ub4 mode )
参数说明:
*svchp——需要断开的服务器句柄;
*errhp——已分配成功的错误类型句柄;若该函数执行出错,则该参数承载出错的原因;
mode——执行模式,目前只有一种模式:OCI_DEFAULT;
该函数使用举例如下:OCIServerDetach(srvhp,
errhp,
(ub4) OCI_DEFAULT)
释放分配的各个句柄:在结束当前会话、断开与数据库的连接后,由于我们手动分配了很多句柄,系统不会自动释放,因而需要手工释放这些句柄,清扫使用环境。OCI8里,使用函数OCIHandleFree来释放各个句柄。
函数原型:sword OCIHandleFree(dvoid *hndlp,ub4 type)
参数说明:
*hndlp——需要释放的句柄;
type——该句柄的类型。参见OCIHandleAlloc函数说明的type参数;
注:使用OCIHandleAlloc函数分配了哪些句柄,那么就需要用该函数释一一放这些句柄;


附录:使用OCI8函数与数据库交互大致步骤

一、定义并初始化所需各变量
envhp、srvhp、errhp、svchp、authp、hndlp、stmthp、等等

 
二、连接数据库
1、 OCIInitialize。初始化OCI程序环境
2、 OCIEnvInit。 初始化OCI环境句柄
3、 OCIHandleAlloc。分配各句柄,需要分配的句柄类型如下:
OCI_HTYPE_SVCCTX,
OCI_HTYPE_ERROR,
OCI_HTYPE_SESSION,
OCI_HTYPE_SERVER,
4、 OCIServerAttach。指定资料源路径
5、 OCIAttrSet。设置各项参数。需要设置的参数类型如下:
OCI_ATTR_SERVER 使用的句柄型为OOCI_HTYPE_SVCCTX
OCI_ATTR_USERNAME
OCI_ATTR_PASSWORD
上面两个参数使用的句柄类型为OCI_HTYPE_SESSION
6、 OCISessionBegin。创建并开始会话
7、 OCIAttrSet。设置会话参数类型OCI_ATTR_SESSION,使用句柄为OCI_HTYPE_SVCCTX
8、 OCIHandleAlloc。分配OCI_HTYPE_STMT型陈述句柄


三、操作数据库
1、OCIStmtPrepare。准备事件处理
2、OCIBindByPos、OCIBindByName(OCIDefineByPos)绑定(定义)变量。如果是多行资料,则需要使用
OCIBindArrayOfStruct(OCIDefineArrayOfStruct)函数来绑定(定义)存放该数据的数组
3、OCIStmtExecute。执行SQL语句
4、OCITransCommit(OCITransRollback)。提交(回滚)当前事务


四、断开数据库
1、OCISessionEnd。结束会话
2、OCIServerDetach。断开与服务器的连接
3、OCIHandleFree。释放已分配的各句柄。需要释放的句柄如下:
OCI_HTYPE_SVCCTX,
OCI_HTYPE_ERROR,
OCI_HTYPE_SESSION,
OCI_HTYPE_SERVER,
OCI_HTYPE_STMT
OCI_HTYPE_ENV


五、提取出错描述信息
1、OCIErrorGet。上述各函数若执行失败,都可以使用该函数来提取出错信息的ORCALE描述。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值