The OceanBase Call Interface (OBCI) driver of OceanBase Database is a C-based driver compatible with Oracle Call Interface (OCI). By using OBCI, applications developed and users created based on OCI can access OceanBase Database in Oracle mode. This topic describes how to configure and use OBCI.
OBCI allows you to access and manage data in OceanBase Database in Oracle mode by using the C language. OBCI provides standard database access features and indexes in the form of dynamic-link libraries (OBCI libraries). Applications can use these features by connecting to these libraries.
OBCI provides the following main features:
Serves as a standard API that can be used to access and process OceanBase Database data in Oracle mode. OBCI provides features such as data definition, data management, data query and processing, and transaction control.
Supports the development of scalable and multi-threaded applications.
Supports SQL access functions that you can use to manage database access, process SQL statements, and manipulate objects retrieved from OBServer nodes.
Supports data type mapping and manipulation functions that allow you to manipulate OceanBase data type attributes.
Use the driver
OceanBase Database provides an RPM package for you to install OBCI. After you download the RPM package, run the following commands in the command-line tool as the root user:
rpm -ivh obci-<version>.x86_64.rpm
V1.1.2 and later
Depend on static libraries
rpm -ivh obci-2.0.3-20220804112948.el7.alios7.x86_64.rpm
Depend on dynamic libraries
rpm -ivh libobclient-2.1.3-20220801173321.el7.alios7.x86_64.rpm
After the RPM package is installed, header files are placed under /u01/obclient/include, and library files are placed under /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 uses the original header files of OCI. If OCI header files have been installed, they can be directly used.
Scenarios and examples
Command used to compile the OCI code:
gcc ob_oci_test.c -I/u01/obclient/include -L/u01/obclient/lib/ \
-loboci -Wl,-rpath /u01/obclient/lib/ -o ob_oci_test.out
Code in the ob_oci_test.c file:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include "oci.h"
/*Declare handles.*/
OCIEnv *envhp; /*The environment handle.*/
OCISvcCtx *svchp; /*The service environment handle.*/
OCIServer *srvhp; /*The server handle.*/
OCISession *authp; /*The session handle.*/
OCIStmt *stmthp; /*The statement handle.*/
OCIDescribe *dschp; /*The description handle.*/
OCIError *errhp; /*The error handle.*/
OCIDefine *defhp[3]; /*The definition handle.*/
OCIBind *bidhp[4]; /*The binding handle.*/
sb2 ind[3]; /*The indicator variable.*/
/*Bind parameters of the select result set.*/
text szpersonid[9]; /*Stores the personid column.*/
text szsex[2]; /*Stores the sex column.*/
text szname[51]; /*Stores the name column.*/
text szemail[51]; /*Stores the mail column.*/
text szphone[26]; /*Stores the phone column.*/
char sql[256]; /*Stores the executed SQL statements.*/
int main(int argc, char *argv[])
{
char strServerName[50];
char strUserName[50];
char strPassword[50];
/*Set the server name, username, and password.*/
strcpy(strServerName, "host:port/db");
strcpy(strUserName, "user");
strcpy(strPassword, "pwd");
/*Initialize the OBCI application environment.*/
OCIInitialize(OCI_DEFAULT, NULL, NULL, NULL, NULL);
/*Initialize the environment handle.*/
OCIEnvInit(&envhp, OCI_DEFAULT, 0, 0);
/*Allocate an environment handle.*/
OCIHandleAlloc(envhp, (dvoid **)&svchp, OCI_HTYPE_SVCCTX, 0, 0);
/*Server environment handle.*/
OCIHandleAlloc(envhp, (dvoid **)&srvhp, OCI_HTYPE_SERVER, 0, 0);
/*Server handle.*/
OCIHandleAlloc(envhp, (dvoid **)&authp, OCI_HTYPE_SESSION, 0, 0);
/*Session handle.*/
OCIHandleAlloc(envhp, (dvoid **)&errhp, OCI_HTYPE_ERROR, 0, 0);
/*Error handle.*/
OCIHandleAlloc(envhp, (dvoid **)&dschp, OCI_HTYPE_DESCRIBE, 0, 0);
/*Descriptor handle.*/
/*Connect to the server.*/
OCIServerAttach(srvhp, errhp, (text *)strServerName,
(sb4)strlen(strServerName), OCI_DEFAULT);
/*Set the username and password.*/
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);
/*Set the attributes of the server environment handle.*/
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);
/*Create and start a user session.*/
OCISessionBegin(svchp, errhp, authp, OCI_CRED_RDBMS, OCI_DEFAULT);
OCIHandleAlloc(envhp, (dvoid **)&stmthp, OCI_HTYPE_STMT, 0, 0);
/*The handle to the SQL statement being processed.*/
/************************************************************************/
/*Query the person table.*/
/************************************************************************/
strcpy(sql, "select personid ,name,phone from person;");
/*Prepare an SQL statement.*/
OCIStmtPrepare(stmthp, errhp, (text *)sql, strlen(sql), OCI_NTV_SYNTAX, OCI_DEFAULT);
/*Bind the output columns.*/
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);
/*Execute the SQL statement*/
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);
}
/************************************************************************/
/*Insert a data record into the person table.*/
/************************************************************************/
memset(sql, 0, sizeof(sql));
strcpy(sql, "insert into person(sex,name,email,phone) values(:sex,:name,:email,:phone);");
/*Prepare an SQL statement.*/
OCIStmtPrepare(stmthp, errhp, (text *)sql, strlen(sql), OCI_NTV_SYNTAX,
OCI_DEFAULT);
/*Bind the input columns.*/
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);
/*Set the input parameters.*/
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");
/*Execute the SQL statement*/
OCIStmtExecute(svchp, stmthp, errhp, (ub4)0, (ub4)0, (CONST OCISnapshot *)0, (OCISnapshot *)0, (ub4)OCI_DEFAULT);
/*Commit data to the database.*/
OCITransCommit(svchp, errhp, OCI_DEFAULT);
/************************************************************************/
/*Update the person table.*/
/************************************************************************/
memset(sql, 0, sizeof(sql));
strcpy(sql, "update person set sex='M',name='test',email='test@mail',phone='1381231313' WHERE personid=1");
/*Prepare an SQL statement.*/
OCIStmtPrepare(stmthp, errhp, (text *)sql, strlen(sql), OCI_NTV_SYNTAX,
OCI_DEFAULT);
/*Execute the SQL statement*/
OCIStmtExecute(svchp, stmthp, errhp, (ub4)0, (ub4)0, (CONST OCISnapshot *)0, (OCISnapshot *)0, (ub4)OCI_DEFAULT);
/*Commit data to the database.*/
OCITransCommit(svchp, errhp, OCI_DEFAULT);
/************************************************************************/
/*Delete a data record from the person table by ID. Make sure that this record exists in this table.
*/
/************************************************************************/
memset(sql, 0, sizeof(sql));
strcpy(sql, "delete from person WHERE personid = :personid");
/*Prepare an SQL statement.*/
OCIStmtPrepare(stmthp, errhp, (text *)sql, strlen(sql), OCI_NTV_SYNTAX,
OCI_DEFAULT);
/*Bind the input parameters.*/
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);
/*Execute the SQL statement*/
OCIStmtExecute(svchp, stmthp, errhp, (ub4)0, (ub4)0, (CONST OCISnapshot *)0, (OCISnapshot *)0, (ub4)OCI_DEFAULT);
/*Commit data to the database.*/
OCITransCommit(svchp, errhp, OCI_DEFAULT);
// End the session.
OCISessionEnd(svchp, errhp, authp, (ub4)0);
// Disconnect from the database.
OCIServerDetach(srvhp, errhp, OCI_DEFAULT);
// Release OCI handles.
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;
}