• ベストアンサー

変数内のデータをmysqlのデータベースへ書き込むサンプルなのですが、うまくinsertされません。

 回答者様たちのおかげで、mysqlをVC++から呼び出すことはできるようになりました。ありがとうございます。  ネットで拾ってきたサンプルを修正し、変数内のデータをtotalというテーブルに書き込んでいくプログラムを書いてみました。  しかし既存のテーブル内のデータは読み込み、表示はできるのですが、書き込みがうまくいきません。  以下、私が書いたソースです。 #include <cstdlib> #include <iostream> #include "windows.h" #include "mysql.h" MYSQL *mysql; MYSQL_RES *results; MYSQL_ROW record; static char *server_options[] = { "mysql_test", "--defaults-file=my.cnf" }; int num_elements = sizeof(server_options)/ sizeof(char *); static char *server_groups[] = { "libmysqld_server", "libmysqld_client" }; //メイン int main(int argc, char **argv) { //mysql_server_init(num_elements, server_options, server_groups); mysql = mysql_init(NULL); //mysql_options(mysql, MYSQL_READ_DEFAULT_GROUP, "libmysqld_client"); //mysql_options(mysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL); char query[256]; int year = 2007; int manth = 2; int day = 2; int hour = 12; int min = 33; int group = 1; int man = 1; char name[] = "紙コップ"; int num = 1; int tanka = 900; int cre = 1; int check; memset(query, '\0', 256); mysql_real_connect(mysql, NULL,"root","パスワード", "rest", 0,NULL,0); if(mysql_errno(mysql) != 0) { fprintf(stderr, "Error: %s\n", mysql_error(mysql)); system("PAUSE"); return 0; } mysql_query(mysql, "SELECT * FROM total"); if(mysql_errno(mysql) != 0) { fprintf(stderr, "Error: %s\n", mysql_error(mysql)); system("PAUSE"); return 0; } results = mysql_store_result(mysql); if(results == NULL || mysql_errno(mysql) != 0) { fprintf(stderr, "Error: %s\n", mysql_error(mysql)); system("PAUSE"); return 0; } /* MYSQL_FIELD *fd; for(int i = 0; fd = mysql_fetch_field(results); i++) { printf("%d %s \n", i, fd->name); } while((record = mysql_fetch_row(results))) { printf("%s %s\n", record[0], record[1]); printf("%s, %s, %s \n", record[2], record[3], record[4]); } */ sprintf(query, "insert into total values (%d, %d, %d, %d, %d, %d, %d, %s, %d, %d, %d)",year, manth, day, hour, min, group, man, name, num, tanka, cre); mysql_query(mysql, query); mysql_free_result(results); mysql_close(mysql); mysql_server_end(); system("PAUSE"); return 1; } データベース名はrest  テーブル名はtotal です。 /**/でかこってある部分は、拾ってきたサンプルで、コメントを外し、 すでにデータが入っているテーブルを指定してやれば、 指定したテーブルのデータを引っ張ってくるので、VC++とmysqlが繋がっていないということはないと思います。 totalのフィールドの数も、書き込みたい変数の数と一致しています。 totalの各フィールドのタイプは、変数nameの紙コップを書き込みたいやつだけVARCHAR型でそれ以外はINT型です。 検索並び替え等はまだ考えてないのでKEY指定はしておりません。 ご指導よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • titokani
  • ベストアンサー率19% (341/1726)
回答No.3

#2です。 「バイナリに変換」というより、文字コードの問題ではないでしょうか? VC++のコードそのままだと、Shift-JISになるので、これがMySQLの設定と合っていないのだと思います。 エラーの感じから、ただの7bitのASCIIになっているのかなという気がします。 これをShift-JISにするか、あるいはEUC,utf-8等にして、VC側でも変換してやるなどすればうまくいきそうな気がします。 具体的な設定方法ですが、当方、PostgreSQLのためよくわかりません。 「MySQL 文字コード」等で検索するといくつかヒットします。参考になるといいのですが。

curve_2008
質問者

お礼

mysql_query(mysql,"SET NAMES SJIS"); mysql_query(mysql, "insert into total values (\"オパオパ\")"); mysql_query(mysql,"SET NAMES SJIS"); 今から飛ばすオパオパはSJISだから余計なことはするな!  という感じのクエリ様です。 いちいちこんなの書かなくていいように設定したはずなのに、 my.ini書き換えたりとか、なんの為の設定だったのだろう。 とりあえずこの一行を足したら幸せになれました。 回答者の皆様、おかげで問題解決しました。 ありがとうございました。 これでcsvからデータを読み込んでデータベースに放り込んでいくというプログラムが完成しました。

curve_2008
質問者

補足

 これが今の私のmysqlのコード設定なのですが、 何か問題がありますでしょうか? インストールした段階でsjisに設定し、 その後my.iniファイルの ・client ・mysql ・mysqld の3か所に default-character-set=sjis を加え、 mysqldのところには skip-character-set-client-handshake を追加。 | character_set_client | sjis | character_set_connection | sjis | character_set_database | sjis | character_set_filesystem | binary | character_set_results | sjis | character_set_server | sjis | character_set_system | utf8 そうするとこうなったのですが、化けます。 http://wota.jp/ac/?date=20061011 http://www.mysql.gr.jp/frame/modules/bwiki/?FAQ#content_1_40 一つ目のアドレス先のサイトで詳しく文字化け対策の説明がなされていて、それによると全部utf8にしてしまえば問題ないと書かれていました。 二つ目のアドレス先では私の設定では文字化けはおきない、とまで書かれておりました。 他のサイトも見てみましたが、今の私の設定で問題ないと書いてあるところもあれば、ujisにするところや、cp932にしているところさまざまです。 私の環境では、いったいどれをどうすればいいのでしょうか? OSはvista、VC++2008でソースを書いてます。 mysqlのverはmysql-5.0.45-win32です。 そして、my.iniファイルのdefault-character-setのところを変更しても、mysqlに反映されておらず、utf8やcp932に書き換えた場合でもsjisとして設定されたままという事態も起きていますので、 合わせてお答えしていただければ非常に助かりますのでお願いいたします。

その他の回答 (2)

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.2

エラーは見れないのでしょうか? >sprintf(query, "insert into total values (%d, %d, %d, %d, %d, %d, %d, %s, %d, %d, %d)",year, manth, day, hour, min, group, man, name, num, tanka, cre); >mysql_query(mysql, query); の後に、 if(mysql_errno(mysql) != 0) { fprintf(stderr, "Error: %s\n", mysql_error(mysql)); system("PAUSE"); return 0; } を入れてみるとか。

curve_2008
質問者

補足

 titokani様、回答ありがとうございます。 投稿する際、このエラー確認部分は実際に書いてはいたのですが コードがみずらいかなと思い省略しておりました。 申し訳ないです。今現在出ているエラーは、以下のものです。 Error: Incorrect string value: '\x8E\x86\x83R\x83b...' for column 'name' at row 1 紙コップが紙コップとして書き込まれていないようです。 今、上記エラーの解決策をリファレンスで確認中ですが、 リファレンスのわかりやすいんだか、わかりずらいんだかよくわからないあの書き方に苦戦中です。 よろしければ、解決方法、もしくは何かしらのアドバイス等いただければありがたいのでよろしくお願いいたします。

  • nmktksk
  • ベストアンサー率36% (75/208)
回答No.1

SQLでは文字(%s)は「'」か「"」で囲む必要があると思います。 確認はしてません。

curve_2008
質問者

お礼

回答ありがとうございます。 nmktsk様の言うとおり、VC++経由ではなく、SQLで直接insertするときには文字列は””で囲う必要があります。 忘れてました。気がつかなかったです。 char name[] = "紙コップ"; の部分を char name[] = "\"紙コップ\""; に変更いたしました。 そうしたところ、SQLの構文エラー表示はなくなりましたが、 別のエラーが出てきました。 ”紙コップ”が、バイナリに変換されてしまっているようです。 これは、VCやmysqlの書き方というより、設定レベルの話のような気がしてきました。 ですので、”から”は変換せずに放りこめ! とアプリケーションに命令する方法を教えていただければ ありがたいです。 よろしくおねがいします!

関連するQ&A