C言語でMySQL バインド変数について
Posted: 2012年5月25日(金) 11:49
初めまして。現在C言語でMySQLを操作しております。
バインド変数を用い、レコードの取得を行なっておりますが、バインド変数に文字列を設定した場合、
レコードの取得が出来ません。
例えば、生徒マスタがあり、レコードの構成が、生徒番号(数値)、生徒氏名(文字列)の場合。
「WHERE 生徒番号 = ?」では取得出来ますが、「WHERE 生徒氏名 = ?」では取得出来ない状態です。
設定がおかしいのでしょうか。いろいろ試したのですが、うまくいきません。
サンプルを用意致しましたので、おかしな点がありましたらご教示ください。
サンプルは「WHERE 生徒氏名= "山田太郎"」の条件で、山田太郎の生徒番号と生徒氏名を取得し、
生徒構造体に設定するといったものです。
サンプルですので、1レコードしか取得しておりません。
以上、よろしくお願い致します。
【メイン関数】
【内部関数】
バインド変数を用い、レコードの取得を行なっておりますが、バインド変数に文字列を設定した場合、
レコードの取得が出来ません。
例えば、生徒マスタがあり、レコードの構成が、生徒番号(数値)、生徒氏名(文字列)の場合。
「WHERE 生徒番号 = ?」では取得出来ますが、「WHERE 生徒氏名 = ?」では取得出来ない状態です。
設定がおかしいのでしょうか。いろいろ試したのですが、うまくいきません。
サンプルを用意致しましたので、おかしな点がありましたらご教示ください。
サンプルは「WHERE 生徒氏名= "山田太郎"」の条件で、山田太郎の生徒番号と生徒氏名を取得し、
生徒構造体に設定するといったものです。
サンプルですので、1レコードしか取得しておりません。
以上、よろしくお願い致します。
【メイン関数】
/* *** インクルード *** */
#include <stdio.h>
#include <winsock.h>
#include <mysql.h>
/* *** 使用内部関数 *** */
short GetSample(MYSQL *mysql, unsigned char *sname, struct student *sp);
/* *** ローカル定数 *** */
/* データベース情報 */
static char *host = "127.0.0.1", /* 接続先(localhost) */
*user = "root", /* 利用者名(root) */
*password = "1234567890", /* パスワード */
*database = "test"; /* データベース名 */
/* 生徒情報 */
struct student
{
short no; /* 生徒番号 */
unsigned char name[255]; /* 生徒氏名 */
};
/**********************/
/* *** メイン関数 *** */
/**********************/
int main(int argc, char *argv[])
{
/* *** 変数 定義 *** */
/* SQL */
MYSQL *mysql; /* 接続情報 */
MYSQL_RES *res; /* クエリの返信データ */
/* 構造体 */
struct student dtstudent = {0}; /* 生徒情報 */
/* その他 */
unsigned char *sname = "山田太郎"; /* 生徒氏名 */
short sret; /* 戻り値 */
int iret; /* 戻り値 */
/* *** プログラム開始 *** */
/* MySQLに接続 */
mysql = mysql_init(NULL); /* mysqlの初期化 */
/* mysqlに接続 */
res = mysql_real_connect(mysql, host, user, password, database, 0, NULL, 0);
if(res == NULL) /* 接続に失敗した場合 */
{
/* エラー内容を出力 */
printf("LINE:[%d] ERROR:%s\n", __LINE__, mysql_error(mysql));
goto END; /* プログラムの末尾へ飛ばす */
}
/* 文字コードの設定 */
iret = mysql_set_character_set(mysql, "utf8"); /* 文字コードを設定 */
if(iret != 0) /* 文字コードの設定がエラーの場合 */
{
/* エラー内容を出力 */
printf("LINE:[%d] iret:[%d] ERROR:%s\n", __LINE__, iret, mysql_error(mysql));
goto END; /* プログラムの末尾へ飛ばす */
}
/* 生徒氏名を指定してレコードを取得 */
printf("【sample】\n");
// *sname = "山田太郎"をメイン関数内で宣言済み
sret = GetSample(mysql, sname, &dtstudent.no); /* レコードを取得 */
if(sret != -1) /* レコードを取得出来た場合 */
{
printf("生徒番号:%d\n", dtstudent.no); /* デバッグ */
printf("生徒氏名:%s\n", dtstudent.name); /* デバッグ */
}
/* MySQLを切断 */
mysql_close(mysql); /* mysqlを切断 */
/* goto END */
END:
return 0;
}/* program end */short GetSample(MYSQL *mysql, unsigned char *sname, struct student *sp)
{
/* *** 変数 定義 *** */
/* SQL */
MYSQL_STMT *stmt = NULL; /* プリペアドステートメント */
MYSQL_BIND bind = {0}, /* バインド */
result[2] = {0}; /* 出力バッファ */
MYSQL_RES *res = NULL; /* クエリの返信データ */
/* 構造体 */
struct student dtstudent = {0}; /* 生徒情報 */
/* その他 */
char sql[255] = {0}; /* SQL文 */
short sinf; /* 戻り値 */
int iret; /* 戻り値 */
my_bool bret; /* 戻り値 */
/* *** プログラム開始 *** */
/* 初期化 */
sinf = -1; /* 戻り値に異常を設定 */
/* SQL文を設定 */
sprintf(sql,
" SELECT "
" STUDENT_NO"
", STUDENT_NAME"
" FROM STUDENT_MST"
" WHERE STUDENT_NAME = ?"
);
/* プリアドステートメントの作成 */
stmt = mysql_stmt_init(mysql); /* プリアドステートメントの作成 */
if( stmt == NULL ) /* メモリ不足の場合 */
{
printf("メモリが不足しています。\n"); /* エラーメッセージを出力 */
goto END; /* プログラムの末尾へ飛ばす */
}
/* SQLの発行 */
iret = mysql_stmt_prepare(stmt, sql, strlen(sql)); /* SQLの発行 */
if(iret != 0) /* エラーが発生した場合 */
{
/* エラー内容を出力 */
printf("LINE:[%d] iret:[%d] ERROR:%s\n", __LINE__, iret, mysql_error(mysql));
goto END; /* プログラムの末尾へ飛ばす */
}
/* バインドの設定 */
bind.buffer_type = MYSQL_TYPE_STRING; /* データ型の設定 */
bind.buffer = sname; /* アドレスの設定 */
bind.buffer_length = 255; /* 文字列の最大の長さを設定 */
/* パラメータの設定 */
bret = mysql_stmt_bind_param(stmt, &bind); /* パラメータの設定 */
if(bret != 0) /* エラーが発生した場合 */
{
/* エラー内容を出力 */
printf("LINE:[%d] bret:[%d] ERROR:%s\n", __LINE__, bret, mysql_stmt_error(stmt));
goto END; /* プログラムの末尾へ飛ばす */
}
/* 出力先バッファの設定 */
/* 生徒番号 */
result[0].buffer_type = MYSQL_TYPE_SHORT; /* データ型の設定 */
result[0].buffer = &dtstudent.no; /* 出力先の設定 */
/* 生徒氏名 */
result[1].buffer_type = MYSQL_TYPE_STRING; /* データ型の設定 */
result[1].buffer = &dtstudent.name[0]; /* 出力先の設定 */
result[1].buffer_length = 255; /* 文字列の最大の長さを設定 */
bret = mysql_stmt_bind_result(stmt, &result[0]); /* バッファの設定 */
if(bret != 0) /* エラーが発生した場合 */
{
/* エラー内容を出力 */
printf("LINE:[%d] bret:[%d] ERROR:%s\n", __LINE__, bret, mysql_stmt_error(stmt));
goto END; /* プログラムの末尾へ飛ばす */
}
/* レコードの取得 */
mysql_stmt_execute(stmt); /* SQL */
iret = mysql_stmt_fetch(stmt); /* 1レコードのデータを取得 */
if(iret == 0) /* 取得に成功した場合 */
{
printf("取得成功。\n"); /* デバッグ用 */
sinf = 0; /* 戻り値を正常に設定 */
}else if(iret == MYSQL_NO_DATA){ /* レコードがない場合 */
printf("レコードがありません。\n"); /* デバッグ用 */
goto END; /* プログラムの末尾へ飛ばす */
}else{ /* 取得に失敗した場合 */
/* エラーメッセージを出力 */
printf("LINE:[%d] iret:[%d] ERROR:%s\n", __LINE__, iret, mysql_stmt_error(stmt));
goto END; /* プログラムの末尾へ飛ばす */
}
*sp = dtstudent; /* 生徒構造体の値を設定 */
/* goto END */
END:
mysql_stmt_close(stmt); /* ステートメントのメモリを開放 */
return sinf;
}/* program end */