No.5ベストアンサー
- 回答日時:
sqlite3_column_ で始まっているルーチン郡は、クエリーの結果セットに関する情報を取り出すのに使います。
って書いてるけど。。
http://hp.vector.co.jp/authors/VA002803/sqlite/c …
だから、書き込みの時に使っても意味なくて、下記のように使うのでは?
sqlite3_prepare(db, "select * from blobtest;", -1, &plineInfo, NULL);
while(sqlite3_step(plineInfo) == SQLITE_ROW) {
int N = sqlite3_column_count(plineInfo);
printf("N=%d\n", N);
}
参考:http://blogs.wankuma.com/episteme/articles/56144 …
この回答への補足
動きました。参考にしたeatblob.cを以下のように修正したら
予定通りに動きました。
ありがとうございました。
int main(int argc, char **argv){
sqlite3 *db;
char *zErrMsg = 0;
char sqtext[256];
int rc;
sqlite3_stmt *plineInfo = 0;
char *line = NULL;
FILE * fp;
int n;
long buflen = 0, totread = 0;
char *buf = NULL, *pbuf = NULL;
rc = sqlite3_open("image.db", &db);
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
exit(1);
}
rc = sqlite3_exec(db, "create table blobtest (des varchar(80), blen INTEGER, b blob);", callback, 0, &zErrMsg);
if( rc!=SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}
if ((fp = fopen("sample.jpg", "rb"))==NULL ) {
fprintf(stderr, "Can't open data: %s\n", "sample.jpg");
return 1;
}
while (buflen - totread - 1 < 1024)
buflen = addmem(&buf, buflen);
pbuf = buf;
totread = 0;
while ((n = fread(pbuf, sizeof(char), 1024, fp)) > 0) {
totread += n;
pbuf[n] = '\0';// This is for printing test
while (buflen - totread - 1 < 1024)
buflen = addmem(&buf, buflen);
pbuf = &buf[totread];
}
fclose(fp);
sprintf(sqtext,"insert into blobtest (des,blen,b) values ('A test file: sample.jpg', %d, ?);", totread);
rc = sqlite3_prepare(db,sqtext , -1, &plineInfo, 0);
if (rc == SQLITE_OK && plineInfo != NULL) {
printf( "SQLITE_OK\n");
sqlite3_bind_blob(plineInfo, 1, buf, totread, free);
while ((rc = sqlite3_step(plineInfo)) == SQLITE_ROW) {
}
rc = sqlite3_finalize(plineInfo);
}
printf("eatblob:%d> ", sqlite3_total_changes(db));
rc = sqlite3_prepare(db, "select * from blobtest;", -1, &plineInfo, 0);
while ((rc = sqlite3_step(plineInfo)) == SQLITE_ROW) {
for (int i = 0; i < sqlite3_column_count(plineInfo); ++i){
print_col(plineInfo, i);
}
printf("\n");
}
rc = sqlite3_finalize(plineInfo);
rc = sqlite3_exec(db, "select * from blobtest;", callback, 0, &zErrMsg);
if( rc!=SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}
sqlite3_close(db);
return 0;
}
No.4
- 回答日時:
テーブルの定義と現在の状態が不明のためあてずっぽうになってしまいますが、
> insert into blobtest (des,blen,b) values ('A test file: sample.jpg', %d, ?);
が失敗している可能性はないですか?
desやblenがユニーク指定されているカラムだと、二回目以降はインサートに失敗してDBに対して影響を与えなかった為、sqlite3_column_countが0を返すことがあると思います。
この回答への補足
お世話になっています。
開発は、
OS Win2000
コンパイラ VC++2005 VC++6.0の二つ
sqlite3.c
を修正して、うえのコンパイラの統合環境で
動くようにしました。(sqlite2.cppと名前をつけました)
1回目で動くかどうか
デバッガで確認してみます。
データベースを削除してから
動かせばよろしいでしょうか?
No.3
- 回答日時:
ん~。
SQLiteを使ったプログラミングの話にシフトしてしまったので、これからは知っている人の回答に期待、ですが、
提示されたコードだけでは、情報が少なすぎるのではないかと直感的に思います。
開発環境と、下記のコードの補足をお願いします。
・データベースの作成(オープン)
・テーブルの作成
・レコードの追加
こちらで時々ご回答されている、epistemeさんの記事が参考になるでしょうか。
http://codezine.jp/a/article/aid/1252.aspx?p=2
この回答への補足
int main(int argc, char **argv){
sqlite3 *db;
char *zErrMsg = 0;
char sqtext[256];
int rc;
sqlite3_stmt *plineInfo = 0;
char *line = NULL;
FILE * fp;
int n;
long buflen = 0, totread = 0;
char *buf = NULL, *pbuf = NULL;
rc = sqlite3_open("image.db", &db);
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
exit(1);
}
rc = sqlite3_exec(db, "create table blobtest (des varchar(80), blen INTEGER, b blob);", callback, 0, &zErrMsg);
if( rc!=SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}
if ((fp = fopen("sample.jpg", "rb"))==NULL ) {
fprintf(stderr, "Can't open data: %s\n", "sample.jpg");
return 1;
}
while (buflen - totread - 1 < 1024)
buflen = addmem(&buf, buflen);
pbuf = buf;
totread = 0;
while ((n = fread(pbuf, sizeof(char), 1024, fp)) > 0) {
totread += n;
pbuf[n] = '\0';// This is for printing test
while (buflen - totread - 1 < 1024)
buflen = addmem(&buf, buflen);
pbuf = &buf[totread];
}
fclose(fp);
sprintf(sqtext,"insert into blobtest (des,blen,b) values ('A test file: sample.jpg', %d, ?);", totread);
rc = sqlite3_prepare(db,sqtext , -1, &plineInfo, 0);
if (rc == SQLITE_OK && plineInfo != NULL) {
printf( "SQLITE_OK\n");
sqlite3_bind_blob(plineInfo, 1, buf, totread, free);
while ((rc = sqlite3_step(plineInfo)) == SQLITE_ROW) {
for (int i = 0; i < sqlite3_column_count(plineInfo); ++i){
//ここに入らない。
print_col(plineInfo, i);
}
printf("\n");
}
rc = sqlite3_finalize(plineInfo);
}
printf("eatblob:%d> ", sqlite3_total_changes(db));
rc = sqlite3_exec(db, "select * from blobtest;", callback, 0, &zErrMsg);
if( rc!=SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}
sqlite3_close(db);
return 0;
}
ありがとうございます。
教えていただいたURLのサンプルと
sqlite3.c を修正して、vc++2005の統合環境で
動くようにした sqlite2.cppを組み合わせたら、
サンプルは正常に動きました。
それと、画像データは
複数回格納できます。
また、plineInfoからの
情報は取り出せないんですが、
代わりの情報(サイズ、名前)をデータベースに登録しておくと
データベースから画像ファイルを取り出せます。
列数は固定でもかまわないので
使えることは使えるのですが
BLOBデータの場合は面倒です。
ほかに、お気づきの点がありましたらよろしくお願いします。
No.2
- 回答日時:
肝心の質問に答えていませんでした。
> これを当てにしないで
> プログラムを組まなくてはいけないのでしょうか?
> 使わなくても動かせそうですか。。。
はい、構造体の実フィールドは何か、ということは当てにせず、
http://www.sqlite.org/c3ref/stmt.html
に書いてあるような、アクセス関数を操作すれば動かせそうです。
(変数の中身は何かしら、更新されるはず)。
実際にやってみたことがないので、恐縮ですが。
>この構造体が見つからないとそこに登録してある値が使えません。
この構造体を引数にして、必要な情報を返すアクセス関数を
探してみると良いかもしれません。
この回答への補足
sprintf(sqtext,"insert into blobtest (des,blen,b) values ('A test file: sample.jpg', %d, ?);", totread);
rc = sqlite3_prepare(db,sqtext , -1, &plineInfo, 0);
//ここで値が入るのが当然と思うが入らないのです。
if (rc == SQLITE_OK && plineInfo != NULL) {
printf( "SQLITE_OK\n");
sqlite3_bind_blob(plineInfo, 1, buf, totread, free);
while ((rc = sqlite3_step(plineInfo)) == SQLITE_ROW) {
for (int i = 0; i < sqlite3_column_count(plineInfo); ++i){
print_col(plineInfo, i);
}
printf("\n");
}
rc = sqlite3_finalize(plineInfo);
}
としても、
sqlite3_column_count(plineInfo);
は、0を返します。
構造体の中身は変化しないのです。
No.1
- 回答日時:
お分かりでないので恐縮ですが、ちょっとgoogleで探してみました。
sqlite3_stmtの実体は隠蔽されていて(いわゆるオブジェクト)
その実体にアクセスするために、以下のようなアクセス関数が
提供されているということではないでしょうか。
int sqlite3_prepare(sqlite3*, const char*, int, sqlite3_stmt**, const char**);
int sqlite3_prepare16(sqlite3*, const void*, int, sqlite3_stmt**, const void**);
int sqlite3_finalize(sqlite3_stmt*);
int sqlite3_reset(sqlite3_stmt*);
バグの混入を防ぐ為に、sqlite3_stmtの内部構造は、直接ユーザーは
知りえない状態にしているように思います。
(いわゆるカプセル化)
外してたらすいません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C#でDBの特定列をUpdate
-
cron
-
ResultSetインターフェイスでの...
-
一度検索されたものに対するソ...
-
INSERT,DELETEを同時に
-
filter_input で取得した型は何...
-
PHPでMySQLのテーブルからcount...
-
MYSQL UPDATE
-
MySQLにmd5が登録できません。
-
変数にNULLを代入したい
-
SQL文が実行できません
-
ユーザーアカウンントの重複を...
-
mysqlにあるemailへそれぞ...
-
sqlの検索結果件数を知りたい
-
読み込んだファイル中の文字列...
-
MySQL接続のPHPの記述に関しまして
-
select文
-
DB::connectでパスワードに「@...
-
PHPからMySQL・異なるDBにコピー
-
PHPでMySQLのデータを2次元配...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
insert1つの処理でもトランザ...
-
Pro*Cの構文エラー
-
JAVA SQLServerException 列名 ...
-
<VB.NET>INSERT文でDBにデータ...
-
VB.NET エラーになる箇...
-
MySQLのINSERT時にたまに重複に...
-
一度検索されたものに対するソ...
-
ResultSetインターフェイスでの...
-
チェックボックスからの複数検...
-
PHP初心者です。syntax error, ...
-
PHP+SQLite でSELECT文のWHERE...
-
エクセルVBAのデータベース接続...
-
PHPよりMySQLの操作のコードの...
-
phpで複数の検索語を検索対象に...
-
php MySQL で、更新ボタンを押...
-
VBA ACCESS SQL...
-
C#でDBの特定列をUpdate
-
PHP&MySQLでの文字列+数列の一...
-
データベースに存在するデータ...
-
ASPでSQL文を使う場合に。
おすすめ情報