0

奇怪的东西。我正在查询一个小型 SQLite 数据库。我想从中得到随机结果。它工作得很好,但是在大约 10-15 次查询之后,我被困在相同的结果上。我显然一定错过了什么,虽然我不知道是什么。这是一些代码,向您展示了我一遍又一遍地调用的方法:

 -(NSString*)setBtnImage:(UIButton*) btn{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *path = [documentsDirectory stringByAppendingPathComponent:@"database.sqlite"];
    NSString *result;
    NSString *resultTemp;
    if (sqlite3_open([path UTF8String], &database) == SQLITE_OK){
        const char *sql = "SELECT * FROM main ORDER BY RANDOM() LIMIT 1;";
        sqlite3_stmt *searchStatement;
        if(sqlite3_prepare_v2(database, sql, -1, &searchStatement, NULL) == SQLITE_OK){
            while (sqlite3_step(searchStatement) == SQLITE_ROW) {
                NSString *mot = [NSString stringWithUTF8String:(char *)sqlite3_column_text(searchStatement, 1)];
                NSString *nom_fichier = [NSString stringWithUTF8String:(char *)sqlite3_column_text(searchStatement, 3)];
                resultTemp = [mot stringByAppendingString:@" "];
                result = [resultTemp stringByAppendingString:nom_fichier];
                UIImage *image = [UIImage imageNamed:nom_fichier];
                [btn setImage:image forState:UIControlStateNormal];
                [btn setTitle:mot forState:UIControlStateNormal];
            }
        }
        sqlite3_finalize(searchStatement);
    }
    return result;
}

因此,您可以看到我从数据库中获取了一个文件名,以便知道将哪个文件应用于按钮。就是这样。它工作得很好,直到我永远停留在相同的结果上。但是,没有错误消息。

我正在使用 Xcode 4.6

任何帮助表示赞赏。

谢谢各位。

4

1 回答 1

0

尝试添加:

sqlite3_close(database);

sqlite3_finalize(searchStatement);

在玩了一段时间后,我在一段时间后再次重新打开数据库时遇到了一个奇怪的 SQLITE_PROTOCOL 错误。该错误表示数据库已锁定。事实证明,如果数据库在使用后没有关闭,就会发生这种情况。您编写例程的方式永远不会关闭数据库,而是每次都重新打开它。由于也没有太多的错误处理,它可能只是看起来你再次得到相同的结果。因为如果发生错误,您只需不设置新按钮图像。虽然我必须说我必须经常打开而不是关闭数据库,而不仅仅是 10-15 次。我有一个循环读取随机数 25 次,当我进入后台和进入前台时,我都这样做了。所以它发生在大约 250 次之后。

但是,您必须做的是添加一些错误日志记录,以便您可以轻松查看发生了什么。因此,在您的代码中添加一些其他分支并 NSLog 它。

我修改后的测试版本如下所示:

-(NSString*)setBtnImage
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *path = [documentsDirectory stringByAppendingPathComponent:@"database2.sqlite"];
    NSString *result;
    // NSString *resultTemp;
    sqlite3 *database;
    int rc = sqlite3_open([path UTF8String], &database) ;
    if (rc == SQLITE_OK){
        const char *sql = "SELECT id FROM log ORDER BY RANDOM() LIMIT 1;";
        sqlite3_stmt *searchStatement;
        int rc = sqlite3_prepare_v2(database, sql, -1, &searchStatement, NULL) ;
        if(rc == SQLITE_OK){
            if (sqlite3_step(searchStatement) == SQLITE_ROW) {
                int r=sqlite3_column_int(searchStatement, 0);
                result = [NSString stringWithFormat:@"%i",r];
            } else {
                result = @"nothing";
            }
            sqlite3_finalize(searchStatement);
        } else {
            NSLog(@"rc=%i",rc);
        }
        sqlite3_close(database);
    } else {
        NSLog(@"could not open rc=%i",rc);
    }

    return result;
}
于 2013-05-16T21:26:55.327 回答