C言語でMySQL バインド変数について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
小太郎

C言語でMySQL バインド変数について

#1

投稿記事 by 小太郎 » 14年前

初めまして。現在C言語でMySQLを操作しております。
バインド変数を用い、レコードの取得を行なっておりますが、バインド変数に文字列を設定した場合、
レコードの取得が出来ません。

例えば、生徒マスタがあり、レコードの構成が、生徒番号(数値)、生徒氏名(文字列)の場合。
「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 */

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: C言語でMySQL バインド変数について

#2

投稿記事 by h2so5 » 14年前

ソースの文字コードはUTF8になっていますか?

小太郎

Re: C言語でMySQL バインド変数について

#3

投稿記事 by 小太郎 » 14年前

h2so5 さんが書きました:ソースの文字コードはUTF8になっていますか?
ご回答頂きありがとうございます。
ソースの文字コードですが、UTF8となっております。

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: C言語でMySQL バインド変数について

#4

投稿記事 by みけCAT » 14年前

ソースの文字コードとデータベースの文字コードは一致していますか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

小太郎

Re: C言語でMySQL バインド変数について

#5

投稿記事 by 小太郎 » 14年前

みけCAT さんが書きました:ソースの文字コードとデータベースの文字コードは一致していますか?
返信が遅くなり申し訳ございません。ご回答頂きありがとうございます。
ソース、データベース、テーブルの文字コードはいずれもUTF8でした。
statusコマンドでMySQLの文字コードを調べたところ、以下となりました。

Server characterset : utf8
Db characterset : utf8
Cliend characterset : cp932
Conn. characterset : cp932

クライアント側から送られる、クエリの文字コードが一致しないようでした。
お手数をお掛け致しました。ありがとうございます。

閉鎖

“C言語何でも質問掲示板” へ戻る