このトピックでは、OBCI ドライバーを使用して OceanBase データベースに接続して使用する方法について説明します。
前提条件
基本的なデータベース開発環境が設定されていること。
次のハードウェア環境が準備されていること。
ハードウェアプラットフォーム: x86_64
オペレーティングシステム: CentOS または Red Hat Enterprise Linux 7.2
コンパイラ: GNU Compiler Collection (GCC) 4.8
OceanBase テクニカルサポートから OBCI と LibOBClient の RPM パッケージを入手していること。
OBCI を使用して OceanBase データベースに接続する
手順 1: データベース接続パラメーターを取得する
詳細については、「接続パラメーターを取得する」をご参照ください。例:
obclient -hxxx.xxx.xxx.xxx -P1521 -u a**** -p******データベース接続パラメーターは、データベースへのアクセスに必要な情報を指定します。サンプルコードで使用する前に、データベースにログオンしてデータベース接続パラメーターを確認できます。
オプション:
-h: 接続先の OceanBase データベースのドメイン名。
-P: OceanBase データベースに接続するためのポート。デフォルトでは、Oracle モードではポートは 1521 です。
-u: テナントアカウントを指定します。
-p: アカウントパスワード。
手順 2: OBCI 関連ドライバーをインストールする
RPM パッケージを取得したら、コマンドラインツールで root ユーザーとして次のコマンドを実行します。
OBCI は LibOBClient に依存しています。そのため、最初に LibOBClient をインストールする必要があります。
$ rpm -ivh libobclient-<version>.x86_64.rpmOBCI をインストールします。
$ rpm -ivh obci-<version>.x86_64.rpmデフォルトでは、パッケージに含まれるプログラムとファイルは次のパスにインストールされます。
ヘッダーファイルは、
/u01/obclient/includeパスにインストールされます。ライブラリファイルは、
/u01/obclient/libパスにインストールされます。
著作権の制限により、新しいバージョンの OBCI を使用したデータベース接続には Oracle Instant Client が必要です。Oracle Instant Client のインストール方法の詳細については、「Oracle Instant Client ダウンロード」を参照してください。
通常、基本パッケージと SDK パッケージをインストールする必要があります。
基本パッケージをインストールします。
$ rpm -ivh oracle-instantclient-basic-<version>.x86_64.rpmSDK パッケージをインストールします。
$ rpm -ivh oracle-instantclient-devel-<version>.x86_64.rpm
手順 3: サンプルコードを作成する
このトピックでは、次の例を使用して、Oracle モードでの OBCI と OceanBase サーバーノード間のインタラクションについて説明します。
OBCI 環境とスレッドを初期化する。
OBCI 環境を初期化する
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)
データベースへの接続を確立し、ユーザセッションを作成する。
ユーザー名を設定する
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)
データ処理の前に、SQL 文を使用して OceanBase サーバーノードとデータを交換する。OBCI アプリケーションで SQL 文を実行する手順:
関数
OCIStmtPrepare()またはOCIStmtPrepare2()を呼び出して、SQL 文を準備する。OCIStmtPrepare(stmthp, errhp, (text *)sql, strlen(sql), OCI_NTV_SYNTAX,OCI_DEFAULT)OCIBindByPos()などの 1 つ以上の関数を呼び出して、入力変数のアドレスを DML 文のプレースホルダーにバインドする。OCIBindByPos(stmthp, &bidhp[0], errhp, 1, &szpersonid, sizeof(szpersonid), SQLT_INT, NULL, NULL, NULL, 0, NULL, 0)OCIBindByName()関数を使用することもできます。OCIBindByName(stmthp, &bidhp[0], errhp, (const OraText*)":personid", 9, &szpersonid, sizeof(szpersonid), SQLT_INT, NULL, NULL, NULL, 0, NULL, 0)関数
OCIStmrExecute()を呼び出して、SQL 文を実行する。OCIStmtExecute(svchp, stmthp, errhp, (ub4)1, (ub4)0, (CONST OCISnapshot *)0, (OCISnapshot *)0, (ub4)OCI_DEFAULT)関数
OCIDefineByPos()を呼び出して、SQL 文のデータ出力項目の出力変数を定義する。OCIDefineByPos(stmthp, &defhp[0], errhp, 1, &szpersonid, sizeof(szpersonid), SQLT_INT, &ind[0], 0, 0, OCI_DEFAULT)関数
OCIStmtFetch()を呼び出して、クエリの結果セットを取得する。OCIStmtFetch(stmthp, errhp, 1, OCI_FETCH_NEXT, OCI_DEFAULT)
ユーザーセッションを終了し、OceanBase データベースから切断する。
セッションを終了する
OCISessionEnd(svchp, errhp, authp, (ub4)0)データベースから切断する
OCIServerDetach(srvhp, errhp, OCI_DEFAULT)
割り当てられたハンドルを解放する。
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)
サンプルコード
次の例は、test.c ファイルの内容を示しています。
#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 bind handle.*/
sb2 ind[3]; /*The indicator variable.*/
/*Bind result set parameters of SELECT statements.*/
int szpersonid; /*Stores the personid column.*/
text szname[51]; /*Stores the name column.*/
text szemail[51]; /*Stores the mail 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, "xxx.xxx.xxx.xxx:1521");
strcpy(strUserName, "a****");
strcpy(strPassword, "******");
/*Initialize the OCI 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.*/
/************************************************************************/
/*Create a table named person.*/
/************************************************************************/
static text* SQL_CREATE_TB = (text*)"create table person(personid number, name varchar(256), email varchar(256))";
/*Prepare the SQL statement.*/
OCIStmtPrepare(stmthp, errhp, SQL_CREATE_TB, strlen((char *)SQL_CREATE_TB),OCI_NTV_SYNTAX, OCI_DEFAULT);
/*Execute the SQL statement.*/
OCIStmtExecute(svchp, stmthp, errhp, 1, 0, 0, 0, OCI_DEFAULT);
/*Commit data to the database.*/
OCITransCommit(svchp, errhp, OCI_DEFAULT);
/************************************************************************/
/*Insert data.*/
/************************************************************************/
memset(sql, 0, sizeof(sql));
strcpy(sql, "insert into person values(:personid,:name,:email)");
/*Prepare the SQL statement.*/
OCIStmtPrepare(stmthp, errhp, (text *)sql, strlen(sql),OCI_NTV_SYNTAX, OCI_DEFAULT);
/*Bind the input columns.*/
OCIBindByName(stmthp, &bidhp[0], errhp, (const OraText*)":personid", 9, &szpersonid, sizeof(szpersonid), SQLT_INT, NULL, NULL, NULL, 0, NULL, 0);
OCIBindByName(stmthp, &bidhp[2], errhp, (const OraText*)":name", 5, szname, sizeof(szname), SQLT_STR, NULL, NULL, NULL, 0, NULL, 0);
OCIBindByName(stmthp, &bidhp[3], errhp, (const OraText*)":email", 6, szemail, sizeof(szemail), SQLT_STR, NULL, NULL, NULL, 0, NULL, 0);
/*Set the input parameters.*/
szpersonid = 1;
memset(szname, 0, sizeof(szname));
strcpy((char*)szname, "obtest");
memset(szemail, 0, sizeof(szemail));
strcpy((char*)szemail, "t@ob.com");
/*Execute the SQL statement.*/
OCIStmtExecute(svchp, stmthp, errhp, (ub4)1, (ub4)0, (CONST OCISnapshot *)0, (OCISnapshot *)0, (ub4)OCI_DEFAULT);
/*Commit data to the database.*/
OCITransCommit(svchp, errhp, OCI_DEFAULT);
/************************************************************************/
/*Query the person table.*/
/************************************************************************/
strcpy(sql, "select personid ,name,email from person;");
/*Prepare the SQL statement.*/
OCIStmtPrepare(stmthp, errhp, (text *)sql, strlen(sql), OCI_NTV_SYNTAX, OCI_DEFAULT);
/*Bind the output columns.*/
OCIDefineByPos(stmthp, &defhp[0], errhp, 1, &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 *)szemail, sizeof(szemail), 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", "email");
while ((OCIStmtFetch(stmthp, errhp, 1, OCI_FETCH_NEXT, OCI_DEFAULT)) != OCI_NO_DATA)
{
printf("%-10d", szpersonid);
printf("%-10s", szname);
printf("%-10s\n", szemail);
break;
}
/*Commit data to the database.*/
OCITransCommit(svchp, errhp, OCI_DEFAULT);
/************************************************************************/
/*Drop the person table.*/
/************************************************************************/
static text* SQL_DROP_TB = (text*)"drop table person";
/*Prepare the SQL statement.*/
OCIStmtPrepare(stmthp, errhp, (text*)SQL_DROP_TB, strlen((char *)SQL_DROP_TB), OCI_NTV_SYNTAX, OCI_DEFAULT);
/*Execute the SQL statement.*/
OCIStmtExecute(svchp, stmthp, errhp, 1, 0, 0, 0, OCI_COMMIT_ON_SUCCESS);
/*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;
}コード内のデータベース接続パラメーターを変更します。次のパラメーターと形式を参照してください。パラメーター値は手順 1 で取得します。
strcpy(strServerName, "xxx.xxx.xxx.xxx:1521");
strcpy(strUserName, "a****");
strcpy(strPassword, "******");strServerName: 接続先の OceanBase データベースのドメイン名とポート。
-hオプションと-P-Pオプションに対応します。Oracle テナントの場合、デフォルトのポート番号は 1521strUserName: テナントアカウント。
-uオプションに対応します。strPassword: テナントアカウントのパスワード。
-pオプションに対応します。
手順 4: サンプルコードを実行する
コードを編集した後、次のコマンドを実行します。
$ gcc test.c -I/u01/obclient/include /u01/obclient/lib/libobci.a -L/usr/local/lib64 -lstdc++ -lpthread -ldl -lm -g -o test新しいバージョンの OBCI を使用する場合は、Oracle Instant Client をインストールします。-I は、次の例に示すように、Oracle ディレクトリを使用する必要があります。
$ gcc test.c -I/usr/include/oracle/21/client64/ -L/u01/obclient/lib/ -L/usr/local/lib64 -lobci -lobclnt -g -o testコンパイル後、実行パスを指定します。
$ export LD_LIBRARY_PATH=/u01/obclient/libサンプルコードを実行します。
$ ./test次の結果が返された場合、データベースに接続され、サンプル文が正しく実行されています。
PERSONID NAME email 49 obtest t@ob.com