LINUX.ORG.RU

C/SQLite что за ошибка

 ,


0

1

Помите найти причину ошибки. В базу данные вставляются.

int main(int argc, char **argv){
  sqlite3 *db;
  sqlite3_open(argv[1], &db);
  sqlite3_stmt *stmt;
  char const * sqlRequest = "INSERT INTO MyTable (dict_id, value) VALUES (?,?);";
  for(int n=1; n<=2;++n){
              if(sqlite3_prepare(db, sqlRequest,-1,&stmt,0))
                       fprintf(stderr, "error1: %s\n", sqlite3_errmsg(db));
              sqlite3_bind_int(stmt,1,n); 
              sqlite3_bind_double(stmt,2,3.14*n); 
              if(sqlite3_step(stmt)  != SQLITE_OK) 
                       fprintf(stderr, "error2: %s\n", sqlite3_errmsg(db));
              sqlite3_reset(stmt);
  }
  sqlite3_finalize(stmt);
  sqlite3_close(db);
  return 0;
}

в ходе работы приложение выдает:

error2: unknown error
error2: unknown error
CREATE TABLE "Dict" (
    "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
    "name" varchar(2) NOT NULL,
    "note" varchar(100) NOT NULL
)
;
CREATE TABLE "MyTable" (
    "dict_id" integer NOT NULL REFERENCES "Dict" ("id"),
    "value" real NOT NULL,
    PRIMARY KEY( "dict_id" )
)
;
CREATE INDEX "MyTable_0137dbe1" ON "MyTable" ("dict_id");

INSERT INTO Dict ("name", "note") VALUES ("Линукс","Ubuntu, Debian, ...");
INSERT INTO Dict ("name", "note") VALUES ("Виндовс","XP, 7, ...");


Последнее исправление: CYB3R (всего исправлений: 1)

Надо делать

if(sqlite3_step(stmt)  != SQLITE_DONE)
вместо SQLITE_OK.

Заодно уж, почему бы не возъюзать sqlite_prepare_v2, который точно такой же, только лучше?

LeninGad
()
Последнее исправление: LeninGad (всего исправлений: 1)
Ответ на: комментарий от developer-cpp

Тяжко — в смысле, медленно и печально?

1. prepare (а особенно prepare_v2) делается один раз, нефиг его в цикле гонять, там должно быть bind/step/reset.

2. делать кучу insert'ов лучше (быстрее) в одной транзакции.

LeninGad
()
Ответ на: комментарий от LeninGad

Спасибо!

1. вынос за цикл prepare ускорил программу

2. я так понимаю так как самая большая задержка в step, то insert-ы нужно накопить так

char const * sqlRequest = "INSERT INTO MyTable (dict_id, value) VALUES (?,?);INSERT INTO MyTable (dict_id, value) VALUES (?,?); ...";

или так

char const * sqlRequests = { ...}

и одина раз сделать step()?

пробую

developer-cpp
() автор топика

какого хрена в тегах делает cpp?

anonymous
()
Ответ на: комментарий от developer-cpp

почему?

Почему одна транзакция с несколькими insert'ами лучше нескольких транзакций по одному insert'у каждая? Или почему это лучше динамической генерации SQL запроса?

i-rinat ★★★★★
()
Ответ на: комментарий от developer-cpp

На самом деле это одна транзакция — потому оно и быстро.

Если делать sqlite3_exec(...,«BEGIN»...) и sqlite3_exec(...,«COMMIT»...) вокруг цикла с bind/step/reset, вставляя по одной строке на каждый step, заметной разницы с вашим кодом в производительности быть не должно. Но с вашим кодом вы упрётесь в SQLITE_MAX_VARIABLE_NUMBER (default 999) на пятистах элементах. Кроме того, если такие массовые вставки делаются из программы несколько раз с разным количеством строк, prepared statement в вашем случае придётся каждый раз создавать заново, а в моём случае его можно хранить.

LeninGad
()

Господи, кто-то ещё обращается к базам данных из программы на С?..

sT331h0rs3 ★★★★★
()
Последнее исправление: sT331h0rs3 (всего исправлений: 1)
Ответ на: комментарий от LeninGad

Спасибо!

Записей будет много.

Действительно, вот так работает быстро:

sqlite3_exec(db, "BEGIN", NULL, NULL, &msg);
   for(int n=0; n<N;++n) {
              sqlite3_prepare_v2(...);
              sqlite3_bind_(...); 
              sqlite3_step(...) ;
              sqlite3_reset(...);
   }
sqlite3_exec(db, "COMMIT;", NULL, NULL, &msg);

developer-cpp
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.