c/c++ で mysql のデータベースへアクセスする方法をまとめます。
rubyやphpと比べるとc/c++でのコーディングはかなり面倒ですが、うまく記述できればパフォーマンスがかなり向上できるようです。
参考URL
DBへの接続
#include <mysql.h> MYSQL mysql; mysql = mysql_init(NULL); if (NULL==mysql) { // 初期化失敗 } const char *hostname = NULL; const char *username = "user"; const char *password = "pass"; const char *database = "database-name"; unsigned long portnumber = 0; if (NULL==mysql_real_connect(mysql, hostname, username, database, portnumber, NULL, 0) { // 接続エラー printf("error: %s\n", mysql_error(mysql)); } else { // 接続成功 }
クエリの発行
int r; r = mysql_query(mysql, "CREATE TABLE hoge (id integer)" ); if (r) { // 失敗 printf("error: %s\n", mysql_error(mysql)); } else { // 成功 }
Prepared Statement の作成
const char *query = "SELECT * FROM HOGEHOGE WHERE ID = ?"; MYSQL_STMT *stmt = mysql_stmt_init(mysql); if (!stmt) { // 失敗時 } int r; r = mysql_stmt_prepare(stmt, query, strlen(query)); if (r) { // 失敗時 }
Prepared Statement へのパラメータの設定
MYSQL_BIND 構造体の配列を用意し、各要素にパラメータを保存している変数のポインタを渡す。たとえば int 型の変数 value の値を bind したい場合は、以下のとおり。
int value = 1234; MYSQL_BIND bind[1]; bind[0].buffer_type = MYSQL_TYPE_LONG; bind[0].buffer = &value; bind[0].is_null = 0; if (mysql_stmt_bind_param(stmt, bind)) { // エラー処理 printf("error: %s\n", mysql_stmt_error(stmt)); }
Prepared Statement の出力先バッファの設定
SELECT 文等の結果を返すクエリを発行する場合は、mysql_stmt_bind_result関数を使ってあらかじめ結果の保存先メモリ領域を設定しておく。
まずPrepared Statementの出力のカラム数 num_fields を求める。
MYSQL_RES *res = mysql_stmt_result_metadata(stmt);
assert(res);
int num_fields = mysql_num_fields(res);
mysql_free_result(res);
次に num_fields 個の MYSQL_BIND を用意し、それぞれにバッファを割り当てる。
たとえば、0 番目のカラムの出力を、int型の変数 output に保存する場合は、
int output ; MYSQL_BIND result[num_fields]; result[0].buffer_type = MYSQL_TYPE_LONG; result[0].buffer = &output; result[0].is_null = 0;
となる。 同様に、配列resultの全要素を設定したら、最後に
if (mysql_stmt_bind_result(stmt, result)) { // エラー処理 printf("error: %s\n", mysql_stmt_error(stmt)); }
で、バッファを stmt に設定する。
Prepared Statement の実行
実行は、mysql_stmt_execute(stmt) を呼ぶだけ。
if (mysql_stmt_execute(stmt)) { // エラー処理 printf("error: %s\n", mysql_stmt_error(stmt)); }
MYSQL_BIND で 変数 value を stmt にバインドしてあるので、
パラメータを変更しながらクエリを繰り返し発行するときは、
value = 1; mysql_stmt_execute(stmt); value = 2; mysql_stmt_execute(stmt);
とすれば良い。
Prepared Statement の結果の取得
レコードを一つづつfetchしていく。こちらも 変数
output を stmt にバインドしてあるため、以下のような簡潔なコードで記述できる。
int r; while ( (r = mysql_stmt_fetch(stmt)) == 0 ) { printf("output: %d\n", output); } if (MYSQL_NO_DATA != r) { // エラー処理 printf("error: %s\n", mysql_stmt_error(stmt)); }
NUL の扱い
mysql_stmt_bind_param() で NULL を指定するには
bind[0].buffer_type = MYSQL_TYPE_NULL;
とする。
mysql_stmt_bind_result() で NULL を取得したい場合は
my_bool isNull;
bind[0].is_null = &isNull;
と MYSQL_BIND の is_null メンバを使う。
オライリージャパン
売り上げランキング: 1133