本記事では、OceanBase Connector/C と OceanBase データベースを使用してアプリケーションを構築し、テーブルの作成、データの挿入、クエリなどの基本的な操作を実現する方法を紹介します。
前提条件
- OceanBaseデータベースをインストールし、Oracleモードのユーザーテナントを作成していること。OceanBaseデータベースのインストールに関する詳細は、デプロイの概要を参照してください。
- OceanBase Connector/Cドライバーをインストールしていること。OceanBase Connector/CドライバーのWindows版インストールパッケージは、テクニカルサポートにお問い合わせください。
- Visual Studioがインストールされていること。
手順
説明
本記事で示す操作手順は、Windows環境でVisual Studio Community 2019を使用してこのプロジェクトをコンパイルおよび実行する場合のものです。他のOS環境やコンパイラを使用する場合は、手順が若干異なる可能性があります。
c-oceanbase-capiプロジェクトを開きます。c-oceanbase-capiプロジェクトのプロパティを設定します。- OceanBaseデータベースの接続情報を取得します。
c-oceanbase-capiプロジェクト内のデータベース接続情報を修正します。- プロジェクトをビルドします。
- アプリケーションを実行します。
- 出力結果を確認します。
ステップ1:c-oceanbase-capiプロジェクトを開く
Visual Studio Community 2019を起動します。
既存のプロジェクトを開きます。
Visual Studio Community 2019の開始画面で、使用を開始する前に プロジェクトまたはソリューションを開く(P) ボタンをクリックします。または、Visual Studio Community 2019の開始画面で、使用を開始する前に コードなしで続行(W) ボタンをクリックするか、上部のメニューバーから ファイル > 開く > プロジェクト/ソリューション(P) を選択します。
c-oceanbase-capi プロジェクト フォルダに移動し、プロジェクトファイル(
c-oceanbase-capi.slnまたはc-oceanbase-capi.vcxproj)を選択して 開く をクリックします。
ステップ2:c-oceanbase-capiプロジェクトのプロパティを設定する
プロジェクトのプロパティページを開きます。
ソリューションエクスプローラー で選択したプロジェクトを右クリックし、コンテキストメニューから プロパティ を選択するか、Visual Studioの上部メニューバーで プロジェクト -> プロパティ を選択するか、ショートカットキー Alt + Enter を使用します。
構成マネージャーの設定を行います。
プロパティページで、上部にある 設定(C) のドロップダウンメニューを選択します。ドロップダウンメニューで、Debug を選択します。
プロパティページで、上部にある プラットフォーム(P) のドロップダウンメニューを選択します。ドロップダウンメニューで、x64 を選択します。
コンパイラのヘッダーファイルパスを設定します。
プロパティページで VC++ディレクトリ タブを選択し、インクルードディレクトリ 項目を見つけて、OceanBase Connector/Cライブラリのヘッダーファイルパスを追加します。
コンパイラのリンクライブラリパスを設定します。
プロパティページで VC++ディレクトリ タブを選択し、ライブラリディレクトリ 項目を見つけて、OceanBase Connector/Cライブラリのリンクライブラリパスを追加します。
文字セットの設定を行います。
プロパティページで 詳細設定 タブを選択し、文字セット 項目を見つけます。ドロップダウンメニューで、マルチバイト文字セットを使用する を選択します。
ステップ3:OceanBaseデータベース接続情報を取得する
OceanBaseデータベースのデプロイ担当者または管理者から、該当するデータベース接続文字列を取得します。
例:
obclient -hxxx.xxx.xxx.xxx -P2881 -usys@oracle001 -p******
パラメータ説明:
-h:OceanBaseデータベースの接続IPアドレスを指定します。ODP接続方式ではODPアドレスを使用し、直接接続方式ではOBServerノードのIPアドレスを使用します。-P:OceanBaseデータベースの接続ポートを指定します。ODP接続方式のデフォルトポートは2883で、ODPデプロイ時にカスタマイズ可能です。直接接続方式のデフォルトポートは2881で、OceanBaseデータベースのデプロイ時にカスタマイズ可能です。-u:テナントの接続アカウントを指定します。ODP接続の一般的な形式はユーザー名@テナント名#クラスタ名またはクラスタ名:テナント名:ユーザー名です。直接接続方式の形式はユーザー名@テナント名です。-p:アカウントのパスワードを指定します。
接続文字列の詳細については、OBClientを使用してOceanBaseテナントに接続するを参照してください。
ステップ4:c-oceanbase-capiプロジェクトのデータベース接続情報を修正する
ステップ3:OceanBaseデータベース接続情報を取得する の情報に基づいて、test_tbl1.cpp ファイル内のデータベース接続情報を修正します。
例:
if (NULL == mysql_real_connect(&con_oboracle, "xxx.xxx.xxx.xxx", "sys@oracle001", "******", "sys", 2881, NULL, 0))
ステップ5:プロジェクトをビルドする
ビルド メニューを選択し、ソリューションのビルド を選択します。ビルド中、コンパイラの出力およびエラーや警告情報が表示されます。
ステップ6:アプリケーションを実行する
デバッグ メニューを選択し、デバッグの開始 または 実行の開始(デバッグなし) を選択してアプリケーションを実行します。
ステップ7:出力結果を確認する
出力結果はデバッグコンソールに表示されます。プログラムの設計ロジックとコードに基づいて、出力の処理方法を判断できます。
プロジェクトコードについて
c-oceanbase-capi をクリックしてプロジェクトコードをダウンロードします。これは、c-oceanbase-capi.zip という名前の圧縮ファイルです。
解凍すると、c-oceanbase-capi という名前のフォルダが作成されます。ディレクトリ構造は以下のとおりです:
c-oceanbase-capi
├─ c-oceanbase-capi.sln
├─ c-oceanbase-capi.vcxproj
├─ c-oceanbase-capi.vcxproj.filters
├─ c-oceanbase-capi.vcxproj.user
└─ test_tbl1.cpp
ファイルの説明:
c-oceanbase-capi.sln:Visual Studioのソリューションファイルで、1つまたは複数のプロジェクトを管理するために使用されます。c-oceanbase-capi.vcxproj:Visual Studioのプロジェクトファイルで、C/C++プロジェクトの構造と設定を記述するために使用されます。c-oceanbase-capi.vcxproj.filters:Visual Studioのプロジェクトフィルターファイルで、プロジェクト内のファイルのディレクトリ構造と編成方法を定義するために使用されます。c-oceanbase-capi.vcxproj.user:ユーザー固有のプロジェクト設定を格納するファイルです。test_tbl1.cpp:データテーブルの構造を定義し、データテーブル操作を実装したソースコードファイルです。
test_tbl1.cppファイルのコード紹介
test_tbl1.cpp ファイルは、test_tbl1 という名前のデータテーブルを定義するために使用され、データテーブルの作成、データの挿入、クエリ操作を実装しています。
本記事の test_tbl1.cpp ファイルのコードは、主に以下の部分で構成されています:
- ヘッダーファイルとライブラリファイルのインポート。
- ヘッダーファイル
stdio.h、stdlib.h、mysql.hをインポートします。 - リンカーが特定のライブラリファイル
Shlwapi.lib、ws2_32.lib、Crypt32.lib、Secur32.lib、obclnt.libをリンクするよう指定します。これらのライブラリファイルは、それぞれ Windows API ライブラリ、WinSock ライブラリ、暗号化ライブラリ、セキュリティライブラリ、および OceanBase データベースクライアントライブラリです。
コード:
#include <stdio.h>
#include <stdlib.h>
#include <mysql.h>
#pragma comment(lib, "Shlwapi.lib")
#pragma comment( lib, "ws2_32.lib" )
#pragma comment(lib, "Crypt32.lib")
#pragma comment(lib, "Secur32.lib")
#pragma comment(lib, "obclnt.lib")
main関数の定義。プログラムのエントリ関数
mainを定義し、整数値を返します。main関数内では、データベースへの接続やデータ操作に関連するコードを記述します。コード:
int main() { // 接続インスタンスオブジェクトの作成 // データベースへの接続 // テーブルの作成 // データの挿入 // データのクエリ // ... }変数と配列の宣言。
con_oboracleという名前の変数を宣言し、その型を MYSQL とします。この変数を宣言することで、接続インスタンスを作成できます。sql_strという名前の文字配列を宣言し、長さを1024に設定します。初期値は{ 0 }です。この配列は SQL クエリ文を格納するために使用されます。
コード:
MYSQL con_oboracle;
char sql_str[1024] = { 0 };
接続インスタンスオブジェクトの初期化。
接続オブジェクト
con_oboracleを初期化し、初期化結果に応じて適切な処理を行います。初期化に失敗した場合は、エラーメッセージを出力して非ゼロ値を返します。初期化に成功した場合は、成功メッセージを出力して、後続の操作を続行します。具体的な手順は以下のとおりです:mysql_init()関数を呼び出して、接続オブジェクトcon_oboracleを初期化します。この関数は初期化された接続オブジェクトへのポインタを返します。初期化に失敗した場合はNULLを返します。NULLはヌルポインタを表すマクロです。NULLとmysql_init()の戻り値を比較して、初期化の成功・失敗を判断します。fprintf()関数は、エラーメッセージを標準エラーストリームstderrに出力するために使用されます。fprintf()関数の最初のパラメータは出力ストリーム、"Error: %s\n"はフォーマット文字列、mysql_error(&con_oboracle)はフォーマット文字列内の%sを置き換える実際のパラメータです。mysql_error(&con_oboracle)は接続オブジェクトcon_oboracleのエラー情報を取得します。return 1を使用して、初期化に失敗した場合はmain関数を終了し、非ゼロ値を返します。この値はプログラムの異常終了または初期化失敗の状態を表すために使用できます。初期化に成功した場合、成功メッセージを出力します。これにより、コンソールで接続オブジェクトの初期化が成功したかどうかを確認できます。
**コード:**
```c
if (NULL == mysql_init(&con_oboracle)) {
fprintf(stderr, "Error: %s\n", mysql_error(&con_oboracle));
return 1;
}
printf("mysql_init() success\n");
```
データベースへの接続。
プログラム内でデータベースへの接続を試み、接続結果に応じて適切な処理を行います。接続に失敗した場合は、エラーメッセージを出力して非ゼロ値を返します。接続に成功した場合は、成功メッセージを出力して、後続の操作を続行します。具体的な手順は以下のとおりです:
mysql_real_connect()関数を呼び出して、データベースに接続します。この関数は接続されたオブジェクトへのポインタを返します。接続に失敗した場合はNULLを返します。fprintf()関数は、エラーメッセージを標準エラーストリームstderrに出力するために使用されます。fprintf()関数の最初のパラメータは出力ストリーム、"Error: %s\n"はフォーマット文字列、mysql_error(&con_oboracle)はフォーマット文字列内の%sを置き換える実際のパラメータです。mysql_error(&con_oboracle)は接続オブジェクトcon_oboracleのエラー情報を取得します。return 1を使用して、接続に失敗した場合はmain関数を終了し、非ゼロ値を返します。この値はプログラムの異常終了または接続失敗の状態を表すために使用できます。接続に成功した場合、成功メッセージを出力します。これにより、コンソールでデータベースへの接続が成功したかどうかを確認できます。
コード:
if (NULL == mysql_real_connect(&con_oboracle, "your_ip", "your_user", "your_password", "your_schema", your_port, NULL, 0)) { fprintf(stderr, "Error: %s\n", mysql_error(&con_oboracle)); return 1; } printf("mysql_real_connect() success\n");OceanBaseデータベースへの接続に必要なパラメータの説明:
your_ip:OceanBaseデータベースの接続IPアドレス。ODP接続方式ではODPアドレスを使用し、直接接続方式ではOBServerノードのIPアドレスを使用します。your_user:テナントの接続アカウント。ODP接続方式の形式:ユーザー名@テナント名#クラスタ名またはクラスタ名:テナント名:ユーザー名。直接接続方式の形式:ユーザー名@テナント名。your_password:アカウントのパスワード。your_schema:アクセスするSchema名。your_port:OceanBaseデータベースの接続ポート。ODP接続方式のデフォルトポートは2883で、ODPデプロイ時にカスタマイズ可能です。直接接続方式のデフォルトポートは2881で、OceanBaseデータベースのデプロイ時にカスタマイズ可能です。
テーブルの作成。
SQLクエリ文を実行してテーブルを作成します。テーブルの作成に成功した場合は成功メッセージを出力し、失敗した場合はエラーメッセージを出力してプログラムを終了します。具体的な手順は以下のとおりです:
sprintf_s()関数を使用してSQLクエリ文字列をフォーマットし、sql_str文字配列に格納します。このSQLクエリ文は、id(主キー)、name、age列を含むtest_tbl1という名前のテーブルを作成するために使用されます。mysql_query()関数を使用してSQLクエリ文を実行します。&con_oboracleはデータベース接続オブジェクトへのポインタで、クエリ操作を実行する接続オブジェクトを指定するために使用されます。sql_strは実行するクエリ文です。その後、クエリの実行結果が成功したかどうかをチェックします。クエリの実行に失敗した場合(戻り値が0ではない場合)、以下のコードブロックを実行します。fprintf()関数は、エラーメッセージを標準エラーストリームstderrに出力するために使用されます。fprintf()関数の最初のパラメータは出力ストリーム、"Error: %s\n"はフォーマット文字列、mysql_error(&con_oboracle)はフォーマット文字列内の%sを置き換える実際のパラメータです。mysql_error(&con_oboracle)は接続オブジェクトcon_oboracleのエラー情報を取得します。データベースとの接続を閉じ、接続オブジェクトのリソースを解放します。
テーブルの作成に失敗した場合、
return 1を使用してmain関数を終了し、非ゼロ値1を返します。これはプログラムが異常終了した状態を表します。テーブルの作成に成功した場合、テーブルが正常に作成されたことを示す成功メッセージを出力します。
コード:
sprintf_s(sql_str, "CREATE TABLE test_tbl1(id NUMBER PRIMARY KEY, name VARCHAR2(50),age NUMBER NOT NULL)"); if (mysql_query(&con_oboracle, sql_str) != 0) { fprintf(stderr, "Error: %s\n", mysql_error(&con_oboracle)); mysql_close(&con_oboracle); return 1; } printf("Table created successfully\n");データの挿入。
SQLクエリ文を実行して、テーブルにデータを挿入します。データの挿入に成功した場合は成功メッセージを出力し、失敗した場合はエラーメッセージを出力してプログラムを終了します。具体的な手順は以下のとおりです:
sprintf_s()関数を使用してSQLクエリ文字列をフォーマットし、sql_str文字配列に格納します。このSQLクエリ文は、test_tbl1テーブルにデータを挿入するために使用されます。挿入するデータには、id、name、age列の値が含まれます。mysql_query()関数を使用してSQLクエリ文を実行します。&con_oboracleはデータベース接続オブジェクトへのポインタで、クエリ操作を実行する接続オブジェクトを指定するために使用されます。sql_strは実行するクエリ文です。その後、クエリの実行結果が成功したかどうかをチェックします。クエリの実行に失敗した場合(戻り値が0ではない場合)、以下のコードブロックを実行します。fprintf()関数は、エラーメッセージを標準エラーストリームstderrに出力するために使用されます。fprintf()関数の最初のパラメータは出力ストリーム、"Error: %s\n"はフォーマット文字列、mysql_error(&con_oboracle)はフォーマット文字列内の%sを置き換える実際のパラメータです。mysql_error(&con_oboracle)は接続オブジェクトcon_oboracleのエラー情報を取得します。データベースとの接続を閉じ、接続オブジェクトのリソースを解放します。
データの挿入に失敗した場合、
return 1を使用してmain関数を終了し、非ゼロ値1を返します。これはプログラムが異常終了した状態を表します。
データの挿入に成功した場合、データが正常に挿入されたことを示す成功メッセージを出力します。
コード:
sprintf_s(sql_str, "INSERT INTO test_tbl1 (id,name,age) VALUES (1,'Tom', 18),(2,'Jerry', 20),(3,'Bob', 22)"); if (mysql_query(&con_oboracle, sql_str) != 0) { fprintf(stderr, "Error: %s\n", mysql_error(&con_oboracle)); mysql_close(&con_oboracle); return 1; } printf("Data inserted successfully\n");データのクエリ。
SQLクエリを実行してテーブル内のデータを取得し、取得したデータを行ごとに出力します。データの取得に成功した場合は成功メッセージを出力し、失敗した場合はエラーメッセージを出力してプログラムを終了します。具体的な手順は以下のとおりです:
sprintf_s()関数を使用してSQLクエリ文字列をフォーマットし、sql_str文字配列に格納します。このSQLクエリ文は、test_tbl1テーブルからすべての列のデータを取得するために使用されます。mysql_query()関数を使用してSQLクエリ文を実行します。&con_oboracleはデータベース接続オブジェクトへのポインタで、クエリ操作を実行する接続オブジェクトを指定するために使用されます。sql_strは実行するクエリ文です。その後、クエリの実行結果が成功したかどうかをチェックします。クエリの実行に失敗した場合(戻り値が0ではない場合)、以下のコードブロックを実行します。fprintf()関数は、エラーメッセージを標準エラーストリームstderrに出力するために使用されます。fprintf()関数の最初のパラメータは出力ストリーム、"Error: %s\n"はフォーマット文字列、mysql_error(&con_oboracle)はフォーマット文字列内の%sを置き換える実際のパラメータです。mysql_error(&con_oboracle)は接続オブジェクトcon_oboracleのエラー情報を取得します。データベースとの接続を閉じ、接続オブジェクトのリソースを解放します。
クエリに失敗した場合、
return 1を使用してmain関数を終了し、非ゼロ値1を返します。これはプログラムが異常終了した状態を表します。
mysql_store_result()関数を使用して、クエリ結果セットをMYSQL_RES構造体に格納します。&con_oboracleはデータベース接続オブジェクトへのポインタで、結果セットを取得する接続オブジェクトを指定します。結果セットが空かどうかをチェックします。結果セットが空の場合、クエリ結果セットの格納に失敗したことを意味し、以下のコードブロックを実行します。
fprintf()関数は、エラーメッセージを標準エラーストリームstderrに出力するために使用されます。fprintf()関数の最初のパラメータは出力ストリーム、"Error: %s\n"はフォーマット文字列、mysql_error(&con_oboracle)はフォーマット文字列内の%sを置き換える実際のパラメータです。mysql_error(&con_oboracle)は接続オブジェクトcon_oboracleのエラー情報を取得します。データベースとの接続を閉じ、接続オブジェクトのリソースを解放します。
クエリ結果セットの格納に失敗した場合、
return 1を使用してmain関数を終了し、非ゼロ値1を返します。これはプログラムが異常終了した状態を表します。
データの取得に成功した場合、データが正常に取得されたことを示す成功メッセージを出力します。
MYSQL_ROW型の変数rowを定義し、各行のデータを格納するために使用します。mysql_fetch_row()関数を使用して、結果セット内のデータを行ごとに取得し、各行のデータをrow変数に格納します。whileループは、結果セット内のすべての行が取得されるまで繰り返し実行されます。ループ内では、各行のデータを出力します。row[0]、row[1]、row[2]は、それぞれ現在の行の最初、二番目、三番目の列の値を表します。
コード:
sprintf_s(sql_str, "SELECT * FROM test_tbl1"); if (mysql_query(&con_oboracle, sql_str) != 0) { fprintf(stderr, "Error: %s\n", mysql_error(&con_oboracle)); mysql_close(&con_oboracle); return 1; } MYSQL_RES* result = mysql_store_result(&con_oboracle); if (result == NULL) { fprintf(stderr, "Error: %s\n", mysql_error(&con_oboracle)); mysql_close(&con_oboracle); return 1; } printf("Data retrieved successfully\n"); MYSQL_ROW row; while ((row = mysql_fetch_row(result)) != NULL) { printf("id: %s, name: %s, age: %s\n", row[0], row[1], row[2]); }プログラム終了。
リソースを解放し、データベースとの接続を閉じます。具体的な手順は以下のとおりです:
mysql_free_result(result)を使用して、mysql_store_result()関数で格納された結果セットのリソースを解放します。resultはMYSQL_RES構造体へのポインタであり、クエリ結果セットの情報とデータを格納しています。mysql_close(&con_oboracle)を使用して、データベースとの接続を閉じ、接続オブジェクトが占有するリソースを解放します。&con_oboracleはデータベース接続オブジェクトへのポインタです。mysql_close()関数を呼び出すことで、データベースとの接続を閉じ、接続オブジェクトに関連するリソースを解放できます。return 0;を使用して、プログラムが正常に終了したことを示し、プログラムの終了ステータスとして0を返します。
コード:
mysql_free_result(result); mysql_close(&con_oboracle); printf("finish\n"); return 0; }
全コード表示
#include <stdio.h>
#include <stdlib.h>
#include <mysql.h>
#pragma comment(lib, "Shlwapi.lib")
#pragma comment( lib, "ws2_32.lib" )
#pragma comment(lib, "Crypt32.lib")
#pragma comment(lib, "Secur32.lib")
#pragma comment(lib, "obclnt.lib")
int main() {
MYSQL con_oboracle;
char sql_str[1024] = { 0 };
if (NULL == mysql_init(&con_oboracle)) {
fprintf(stderr, "Error: %s\n", mysql_error(&con_oboracle));
return 1;
}
printf("mysql_init() success\n");
if (NULL == mysql_real_connect(&con_oboracle, "your_ip", "your_user", "your_password", "your_schema", your_port, NULL, 0)) {
fprintf(stderr, "Error: %s\n", mysql_error(&con_oboracle));
return 1;
}
printf("mysql_real_connect() success\n");
sprintf_s(sql_str, "CREATE TABLE test_tbl1(id NUMBER PRIMARY KEY, name VARCHAR2(50),age NUMBER NOT NULL)");
if (mysql_query(&con_oboracle, sql_str) != 0) {
fprintf(stderr, "Error: %s\n", mysql_error(&con_oboracle));
mysql_close(&con_oboracle);
return 1;
}
printf("Table created successfully\n");
sprintf_s(sql_str, "INSERT INTO test_tbl1 (id,name,age) VALUES (1,'Tom', 18),(2,'Jerry', 20),(3,'Bob', 22)");
if (mysql_query(&con_oboracle, sql_str) != 0) {
fprintf(stderr, "Error: %s\n", mysql_error(&con_oboracle));
mysql_close(&con_oboracle);
return 1;
}
printf("Data inserted successfully\n");
sprintf_s(sql_str, "SELECT * FROM test_tbl1");
if (mysql_query(&con_oboracle, sql_str) != 0) {
fprintf(stderr, "Error: %s\n", mysql_error(&con_oboracle));
mysql_close(&con_oboracle);
return 1;
}
MYSQL_RES* result = mysql_store_result(&con_oboracle);
if (result == NULL) {
fprintf(stderr, "Error: %s\n", mysql_error(&con_oboracle));
mysql_close(&con_oboracle);
return 1;
}
printf("Data retrieved successfully\n");
MYSQL_ROW row;
while ((row = mysql_fetch_row(result)) != NULL) {
printf("id: %s, name: %s, age: %s\n", row[0], row[1], row[2]);
}
mysql_free_result(result);
mysql_close(&con_oboracle);
printf("finish\n");
return 0;
}
関連ドキュメント
OceanBaseデータベースへの接続方法の詳細については、接続方法の概要を参照してください。
OceanBase Connector/Cの詳細については、OceanBase Connector/Cを参照してください。
c-oceanbase-capi サンプルプロジェクトをダウンロード