Вставить словарь в базу данных SQLite не будет работать

Я пытаюсь обновить базу данных SQLite на iPhone с помощью словаря, возвращаемого моим сервером. sqlite3_step возвращает sqlite_ok, но база данных все еще остается пустой. В любом случае, после sqlite3_step вставлен журнал для возможной ошибки, и это возвращение "база данных заблокирована", так что я думаю, что что-то не так с порядком функций sqlite в моем коде. Я также проверил, что словарь содержит данные с журналом внутри итерации, и он дает мне все, что я ожидаю найти.

Что здесь не так? Кто-нибудь может мне помочь? Извините за мой плохой английский и спасибо Марко

 //----- database update -----------------------------------------------------------------------------------------------------
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *dbPath = [documentsDirectory stringByAppendingPathComponent:@"DB.sqlite"];

if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
    hasError= false;         
     const char *update_stmt="REPLACE INTO table VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)";
        sqlite3_stmt *compiledstatement;
        if(sqlite3_prepare_v2(database,update_stmt , -1, &compiledstatement, NULL)==SQLITE_OK) {
            for (NSDictionary *item in [update objectForKey:@"table1"]) {
                sqlite3_bind_int(compiledstatement, 1,[[item objectForKey:@"a"]integerValue]);
                sqlite3_bind_text(compiledstatement,2,[[item objectForKey:@"b"] UTF8String], -1, SQLITE_TRANSIENT);
                sqlite3_bind_text(compiledstatement,3,[[item objectForKey:@"c"] UTF8String], -1, SQLITE_TRANSIENT);
                sqlite3_bind_text(compiledstatement,4,[[item objectForKey:@"d"] UTF8String], -1, SQLITE_TRANSIENT);
                sqlite3_bind_int(compiledstatement,5,[[item objectForKey:@"e"] integerValue]);
                sqlite3_bind_double(compiledstatement,6,[[item objectForKey:@"f"] doubleValue]);
                sqlite3_bind_text(compiledstatement,7,[[item objectForKey:@"g"] UTF8String], -1, SQLITE_TRANSIENT);
                sqlite3_bind_text(compiledstatement,8,[[item objectForKey:@"s"] UTF8String], -1, SQLITE_TRANSIENT);
                sqlite3_bind_text(compiledstatement,9,[[item objectForKey:@"g"] UTF8String], -1, SQLITE_TRANSIENT);
                sqlite3_bind_text(compiledstatement,10,[[item objectForKey:@"u"] UTF8String], -1, SQLITE_TRANSIENT);
                sqlite3_bind_text(compiledstatement,11,[[item objectForKey:@"y"] UTF8String], -1, SQLITE_TRANSIENT);
                sqlite3_bind_int(compiledstatement,12,[[item objectForKey:@"n"] integerValue]);
                sqlite3_bind_int(compiledstatement,13,[[item objectForKey:@"k"] integerValue]);
                //sqlite3_bind_text(compiledstatement,2,[@"" UTF8String], -1, SQLITE_TRANSIENT);
                if(!sqlite3_step(compiledstatement)==SQLITE_DONE) {hasError= true; NSLog(@"error (%s)", sqlite3_errmsg(database));} //error
                NSLog(@"error (%s)", sqlite3_errmsg(database));
                sqlite3_reset(compiledstatement);
            }
            sqlite3_finalize(compiledstatement);
        }else { NSLog(@"prepare FAILED (%s)", sqlite3_errmsg(database));}        
} else {NSLog(@"opening error");}
sqlite3_close(database);

РЕДАКТИРОВАТЬ:

Я не могу понять, почему этот код не работает!!! Я не нашел окончательного решения.

Я всегда получаю "библиотечную процедуру, вызванную вне последовательности" в COMMIT, почему? Разве эта последовательность не верна?

-open -begin -prepare -cycle словарь (bind, step и reset; для каждого элемента в словаре я должен вставить или заменить строку) -finalize -commit -close

Если я удаляю команду begin и commit exec, у меня появляется ошибка "база данных заблокирована" на "шаге", когда код пытается вставить первую строку... это кошмар...

Еще раз спасибо за вашу помощь!!

    //----- database update -----------------------------------------------------------------------------------------------------

const char *updateTags_stmt="REPLACE INTO tags VALUES(?,?,?)";

if (sqlite3_open_v2([dbPath UTF8String], &database,SQLITE_OPEN_READWRITE,NULL) != SQLITE_OK) {
    sqlite3_close(database);return;
}

if (sqlite3_exec(database, "BEGIN", 0, 0, 0)!=SQLITE_OK) {sqlite3_close(database);return;}

sqlite3_stmt *compiledstatement;


    if(sqlite3_prepare_v2(database,updateTags_stmt , -1, &compiledstatement, NULL)!=SQLITE_OK) {sqlite3_close(database);return;}

        for (NSDictionary *item in [update objectForKey:@"tags"]) {
            sqlite3_bind_int(compiledstatement,1,[[item objectForKey:@"tid"] integerValue]);
            sqlite3_bind_text(compiledstatement,2,[[item objectForKey:@"categoria"] UTF8String], -1, SQLITE_TRANSIENT);
            sqlite3_bind_text(compiledstatement,3,[[item objectForKey:@"tag"] UTF8String], -1, SQLITE_TRANSIENT);
            if(sqlite3_step(compiledstatement)!=SQLITE_DONE) {
                sqlite3_finalize(compiledstatement);
                sqlite3_close(database);
                return;
            } else {if (sqlite3_reset(compiledstatement)!=SQLITE_OK){sqlite3_close(database);return;}}
        }
        if (sqlite3_finalize(compiledstatement)!=SQLITE_OK){sqlite3_close(database);return;}



    if (sqlite3_exec(database, "COMMIT", NULL, NULL, 0)!=SQLITE_OK) {sqlite3_close(database);return;}


if (sqlite3_close(database)!=SQLITE_DONE){sqlite3_close(database);return;}

2 ответа

Наконец, я обнаружил проблему: был другой запрос в другом классе, в котором инструкция не была завершена, поэтому БД все еще остается открытой... две недели для этого урока!! хехех извините!

Этот код неверен; сначала инвертирует возвращаемое значение sqlite3_step, а затем сравнивает это значение с SQLITE_DONE (что никогда не удается, потому что ! возвращает 0 или 1):

if(!sqlite3_step(compiledstatement)==SQLITE_DONE)

Сделай это правильно:

if (sqlite3_step(compiledstatement) != SQLITE_DONE)
Другие вопросы по тегам