【问题标题】:Insert dictionary in an SQLite db won't work在 SQLite 数据库中插入字典不起作用
【发布时间】:2013-12-19 15:26:14
【问题描述】:

我正在尝试使用我的服务器返回的字典更新 iPhone 上的 SQLite 数据库。 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 收到“库例程调用乱序”,为什么? 这个顺序不对吗?

-打开 -开始 -准备 -循环字典(绑定、步进和重置;对于字典中的每个项目,我必须插入或替换一行) -最终确定 -犯罪 -关闭

如果我删除开始并提交 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;}

【问题讨论】:

    标签: ios sqlite dictionary database-locking


    【解决方案1】:

    这段代码是错误的;它首先反转sqlite3_step 的返回值,然后将该值与SQLITE_DONE 进行比较(这永远不会成功,因为! 返回0 或1):

    if(!sqlite3_step(compiledstatement)==SQLITE_DONE)
    

    正确地做:

    if (sqlite3_step(compiledstatement) != SQLITE_DONE)
    

    【讨论】:

    • 谢谢!这是错误的,并且正确地执行它会返回错误“库例程调用乱序”所以我在打开数据库之前移动了语句,好的。但现在它给了我“数据库锁定”...再次感谢您
    【解决方案2】:

    最后我发现了问题:在另一个类上存在另一个查询,其中 then 语句没有最终确定,因此数据库仍然始终处于打开状态......本课需要两周时间!呵呵对不起!

    【讨论】:

      猜你喜欢
      • 2015-01-24
      • 2011-12-16
      • 2014-04-21
      • 1970-01-01
      • 2017-10-07
      • 1970-01-01
      相关资源
      最近更新 更多