基于湖库一体架构,统一管理结构化、半结构化与非结构化等多模态数据,一个系统承载事务处理、实时分析与 AI 工作负载。
OBCI 驱动
更新时间:2023-07-18 17:26:00
OceanBase 数据库的 OBCI 驱动是兼容 Oracle 数据库 OCI 接口的 C 语言的驱动。基于 Oracle OCI 开发的用户和应用可以使用 OBCI 驱动访问 OceanBase 数据库的 Oracle 模式。本文介绍了 OBCI 驱动的使用说明和配置方法。
OBCI 使您可以使用 C 语言来访问操作 OceanBase 数据库( Oracle 模式)中的数据。它以动态链接库( OBCI 库)的形式提供了标准数据库访问和索引功能,应用程序在运行阶段链接此库就可以使用这些功能。
OBCI提供的主要功能如下:
OBCI 提供一套标准的 OceanBase Oracle 数据库访问、处理接口,主要包括数据的定义、数据管理、查询处理、事务控制等。
OBCI 的 API 接口可用于支持可扩展、多线程的应用。
支持 SQL 访问函数。可用于管理数据库访问,处理 SQL 语句,和操作从 OceanBase 数据库服务器获取的对象。
支持数据类型映射和操作函数。可用于操作 OceanBase 数据类型属性。
使用说明
OceanBase OCI 提供了 RPM 包进行安装。当您获取 RPM 包后,在命令行工具中以 root 用户权限执行如下命令进行安装:
rpm -ivh obci-<version>.x86_64.rpm
1.1.2 版本及后续版本
依赖静态库
rpm -ivh obci-2.0.3-20220804112948.el7.alios7.x86_64.rpm
依赖动态库
rpm -ivh libobclient-2.1.3-20220801173321.el7.alios7.x86_64.rpm
RPM 安装完之后,相应的头文件会被放置到 /u01/obclient/include 下 , 相应的库文件会被放到 /u01/obclient/lib 下。
[admin@odp-2 odp-2.inc.aplipay.net /u01/obclient/include]
$ ls |grep oci
oci1.h
oci8dp.h
ociap.h
ociapr.h
ocidef.h
ocidem.h
ocidfn.h
ociextp.h
oci.h
ocikpr.h
ocixmldb.h
ocixstream.h
[admin@odp-2 odp-2.inc.aplipay.net /u01/obclient/lib]
$ ls |grep oci
libobci.a
libobci.so
libobci.so.20
libobci.so.20.3.11
obci 使用的是原 oci 的头文件,如果机器之前已经装有 oci 头文件,可以直接使用原来的 oci 头文件。
使用示例
编译 oci 代码所使用的命令如下:
gcc ob_oci_test.c -I/u01/obclient/include -L/u01/obclient/lib/ \
-lobci -Wl,-rpath /u01/obclient/lib/ -o ob_oci_test.out
ob_oci_test.c 的代码文件如下:
/**********************************************************
* Copyright(C) 2014 - 2020 Alibaba Inc. All Rights Reserved.
*
* Filename: ob_oci_test.c
* Description: ----
* Create: 2020-07-07 10:14:59
* Last Modified: 2020-07-07 10:14:59
***********************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include "oci.h"
/*声明句柄*/
OCIEnv *envhp; /*环境句柄*/
OCISvcCtx *svchp; /*服务环境句柄*/
OCIServer *srvhp; /*服务器句柄*/
OCISession *authp; /*会话句柄*/
OCIStmt *stmthp; /*语句句柄*/
OCIDescribe *dschp; /*描述句柄*/
OCIError *errhp; /*错误句柄*/
OCIDefine *defhp[3]; /*定义句柄*/
OCIBind *bidhp[4]; /*绑定句柄*/
sb2 ind[3]; /*指示符变量*/
/*绑定select结果集的参数*/
text szpersonid[9]; /*存储personid列*/
text szsex[2]; /*存储sex列*/
text szname[51]; /*存储name列*/
text szemail[51]; /*存储mail列*/
text szphone[26]; /*存储phone列*/
char sql[256]; /*存储执行的sql语句*/
int main(int argc, char *argv[])
{
char strServerName[50];
char strUserName[50];
char strPassword[50];
/*设置服务器,用户名和密码*/
strcpy(strServerName, "host:port/db");
strcpy(strUserName, "user");
strcpy(strPassword, "pwd");
/*初始化OCI应用环境*/
OCIInitialize(OCI_DEFAULT, NULL, NULL, NULL, NULL);
/*初始化环境句柄*/
OCIEnvInit(&envhp, OCI_DEFAULT, 0, 0);
/*分配句柄*/
OCIHandleAlloc(envhp, (dvoid **)&svchp, OCI_HTYPE_SVCCTX, 0, 0);
/*服务器环境句柄*/
OCIHandleAlloc(envhp, (dvoid **)&srvhp, OCI_HTYPE_SERVER, 0, 0);
/*服务器句柄*/
OCIHandleAlloc(envhp, (dvoid **)&authp, OCI_HTYPE_SESSION, 0, 0);
/*会话句柄*/
OCIHandleAlloc(envhp, (dvoid **)&errhp, OCI_HTYPE_ERROR, 0, 0);
/*错误句柄*/
OCIHandleAlloc(envhp, (dvoid **)&dschp, OCI_HTYPE_DESCRIBE, 0, 0);
/*描述符句柄*/
/*连接服务器*/
OCIServerAttach(srvhp, errhp, (text *)strServerName,
(sb4)strlen(strServerName), OCI_DEFAULT);
/*设置用户名和密码*/
OCIAttrSet(authp, OCI_HTYPE_SESSION, (text *)strUserName,
(ub4)strlen(strUserName), OCI_ATTR_USERNAME, errhp);
OCIAttrSet(authp, OCI_HTYPE_SESSION, (text *)strPassword,
(ub4)strlen(strPassword), OCI_ATTR_PASSWORD, errhp);
/*设置服务器环境句柄属性*/
OCIAttrSet((dvoid *)svchp, (ub4)OCI_HTYPE_SVCCTX,
(dvoid *)srvhp, (ub4)0, OCI_ATTR_SERVER, errhp);
OCIAttrSet(svchp, OCI_HTYPE_SVCCTX, (dvoid *)authp,
0, OCI_ATTR_SESSION, errhp);
/*创建并开始一个用户会话*/
OCISessionBegin(svchp, errhp, authp, OCI_CRED_RDBMS, OCI_DEFAULT);
OCIHandleAlloc(envhp, (dvoid **)&stmthp, OCI_HTYPE_STMT, 0, 0);
/*语句句柄*/
/************************************************************************/
/*查询person表*/
/************************************************************************/
strcpy(sql, "select personid ,name,phone from person;");
/*准备SQL语句*/
OCIStmtPrepare(stmthp, errhp, (text *)sql, strlen(sql), OCI_NTV_SYNTAX, OCI_DEFAULT);
/*绑定输出列*/
OCIDefineByPos(stmthp, &defhp[0], errhp, 1, (ub1 *)szpersonid,
sizeof(szpersonid), SQLT_STR, &ind[0], 0, 0, OCI_DEFAULT);
OCIDefineByPos(stmthp, &defhp[1], errhp, 2, (ub1 *)szname,
sizeof(szname), SQLT_STR, &ind[1], 0, 0, OCI_DEFAULT);
OCIDefineByPos(stmthp, &defhp[2], errhp, 3, (ub1 *)szphone,
sizeof(szphone), SQLT_STR, &ind[2], 0, 0, OCI_DEFAULT);
/*执行SQL语句*/
OCIStmtExecute(svchp, stmthp, errhp, (ub4)0, 0, NULL, NULL,
OCI_DEFAULT);
printf("%-10s%-10s%-10s\n", "PERSONID", "NAME", "PHONE");
while ((OCIStmtFetch(stmthp,
errhp, 1, OCI_FETCH_NEXT, OCI_DEFAULT)) != OCI_NO_DATA)
{
printf("%-10s", szpersonid);
printf("%-10s", szname);
printf("%-10s\n", szphone);
}
/************************************************************************/
/*向person表插入一条数据*/
/************************************************************************/
memset(sql, 0, sizeof(sql));
strcpy(sql, "insert into person(sex,name,email,phone) values(:sex,:name,:email,:phone);");
/*准备SQL语句*/
OCIStmtPrepare(stmthp, errhp, (text *)sql, strlen(sql), OCI_NTV_SYNTAX,
OCI_DEFAULT);
/*绑定输入列*/
OCIBindByName(stmthp, &bidhp[0], errhp, ":sex", 4, szsex,
sizeof(szsex), SQLT_STR, NULL, NULL, NULL, 0, NULL, 0);
OCIBindByName(stmthp, &bidhp[1], errhp, ":name", 5, szname,
sizeof(szname), SQLT_STR, NULL, NULL, NULL, 0, NULL, 0);
OCIBindByName(stmthp, &bidhp[2], errhp, ":email", 6, szemail,
sizeof(szemail), SQLT_STR, NULL, NULL, NULL, 0, NULL, 0);
OCIBindByName(stmthp, &bidhp[3], errhp, ":phone", 6, szphone,
sizeof(szphone), SQLT_STR, NULL, NULL, NULL, 0, NULL, 0);
/*设置输入参数*/
memset(szsex, 0, sizeof(szsex));
strcpy(szsex, "M");
memset(szname, 0, sizeof(szname));
strcpy(szname, "obtest");
memset(szemail, 0, sizeof(szemail));
strcpy(szemail, "t@ob.com");
memset(szphone, 0, sizeof(szphone));
strcpy(szphone, "123456789");
/*执行SQL语句*/
OCIStmtExecute(svchp, stmthp, errhp, (ub4)0, (ub4)0, (CONST OCISnapshot *)0, (OCISnapshot *)0, (ub4)OCI_DEFAULT);
/*提交到数据库*/
OCITransCommit(svchp, errhp, OCI_DEFAULT);
/************************************************************************/
/*更新person表*/
/************************************************************************/
memset(sql, 0, sizeof(sql));
strcpy(sql, "update person set sex='M',name='test',email='test@mail',phone='1381231313' WHERE personid=1");
/*准备SQL语句*/
OCIStmtPrepare(stmthp, errhp, (text *)sql, strlen(sql), OCI_NTV_SYNTAX,
OCI_DEFAULT);
/*执行SQL语句*/
OCIStmtExecute(svchp, stmthp, errhp, (ub4)0, (ub4)0, (CONST OCISnapshot *)0, (OCISnapshot *)0, (ub4)OCI_DEFAULT);
/*提交到数据库*/
OCITransCommit(svchp, errhp, OCI_DEFAULT);
/************************************************************************/
/*删除person表的ID为的数据,首先要在数据库中存在这条记录
*/
/************************************************************************/
memset(sql, 0, sizeof(sql));
strcpy(sql, "delete from person WHERE personid = :personid");
/*准备SQL语句*/
OCIStmtPrepare(stmthp, errhp, (text *)sql, strlen(sql), OCI_NTV_SYNTAX,
OCI_DEFAULT);
/*绑定输入参数*/
memset(szpersonid, 0, sizeof(szpersonid));
strcpy(szpersonid, "7");
OCIBindByPos(stmthp, &bidhp[0], errhp, 1, szpersonid,
sizeof(szpersonid), SQLT_STR, NULL, NULL, NULL, 0, NULL, 0);
/*执行SQL语句*/
OCIStmtExecute(svchp, stmthp, errhp, (ub4)0, (ub4)0, (CONST OCISnapshot *)0, (OCISnapshot *)0, (ub4)OCI_DEFAULT);
/*提交到数据库*/
OCITransCommit(svchp, errhp, OCI_DEFAULT);
//结束会话
OCISessionEnd(svchp, errhp, authp, (ub4)0);
//断开与数据库的连接
OCIServerDetach(srvhp, errhp, OCI_DEFAULT);
//释放OCI句柄
OCIHandleFree((dvoid *)dschp, OCI_HTYPE_DESCRIBE);
OCIHandleFree((dvoid *)stmthp, OCI_HTYPE_STMT);
OCIHandleFree((dvoid *)errhp, OCI_HTYPE_ERROR);
OCIHandleFree((dvoid *)authp, OCI_HTYPE_SESSION);
OCIHandleFree((dvoid *)svchp, OCI_HTYPE_SVCCTX);
OCIHandleFree((dvoid *)srvhp, OCI_HTYPE_SERVER);
return 0;
}
更多信息
有关 OBCI 的详细介绍和使用说明,请参见 《 OceanBase C 语言调用接口》。