须先调用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头文件。 3.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.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));建立数据库会话。此函数隐含申请服务器句柄和用户会话句柄,登录后,句柄是只读的,不能再设置句柄属性。 3.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语句 3.5结束会话断开数据库连接 OCILogoff( m_svchp, m_errhp ); 3.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 OBJS=example.o EXE=exampled,exampled就为生成的可执行文件。 4 二者的比较 PRO*C程序的最大优点是简单易学,另外,因为PRO*C程序是把SQL语句翻译成相应的Oracle库函数调用,因此大大提高了应用程序的执行速度。 OCI程序使开发人员能使用已熟悉的C语言编程技术,通过Oracle的OCI函数调用快速开发应用程序,能充分发挥C语言的特点,使开发人员对程序设计和运行控制更加灵活,开发的应用程序具有更强的数据处理能力和更大的灵活性。 5 结束语 文章从开发环境、开发流程、编译三个方面分别详细分析了PRO*C和OCI程序设计的方法,并对两者的性能进行了比较。希望能为广大的计算机技术工作者提供参考。由于OCI程序设计相对复杂, 上一页 [1] [2] [3] 下一页
Tags:
|